Back to Funclet
SOURCE / PINNED RELEASE

Made of little things.

Funclet

Release
0b497cfc2f66…
Author-recorded commit
1e531b24f490…
License
LICENSE
Author’s source reference
nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-6b7a37cac1d

Archive hash verified: 71d97a89ed8c40c2…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

tests/live-services.mjs
// Candidate service code against a real host. No mock relay responses or identity.
// This checks SDK operations; it does not claim the candidate artifact is published.
import assert from 'node:assert/strict';
import { readFileSync, realpathSync } from 'node:fs';
import { createRequire } from 'node:module';
import { execFileSync } from 'node:child_process';
import { runInNewContext } from 'node:vm';
import ts from 'typescript';
const [url, owner] = process.argv.slice(2);
assert.ok(url && /^(https:\/\/napplet\.soy\/|http:\/\/127\.0\.0\.1:)/.test(url), 'Pass a soyLI preview or napplet.soy release URL');
if (owner) assert.match(owner, /^[a-f0-9]{64}$/);
const require = createRequire(`${realpathSync('node_modules/@napplet/conformance-cli')}/package.json`);
const { chromium } = require('playwright');
const executables = JSON.parse(execFileSync('soyli', ['browser', 'path', '--json'], { encoding: 'utf8' })).executables;
const browser = await chromium.launch({ executablePath: executables.find(x => x.installed && x.name.startsWith('chromium')).path });
function load(name, dependencies = {}) {
  const module = { exports: {} };
  const source = ts.transpileModule(readFileSync(`src/${name}.ts`, 'utf8'), { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 } }).outputText;
  runInNewContext(source, { module, exports: module.exports, URL, Error, require: name => {
    if (!(name in dependencies)) throw new Error(`Unexpected dependency ${name}`);
    return dependencies[name];
  } });
  return module.exports;
}
try {
  const page = await browser.newPage();
  await page.goto(url);
  if (url.startsWith('https:')) await page.getByRole('button', { name: /^Start Funclet$/ }).click({ timeout: 20000 });
  await page.frameLocator('iframe').first().locator('#search').waitFor({ timeout: 30000 });
  const frame = page.frames().find(f => f.url() === 'about:srcdoc');
  const calls = [];
  const outbox = { async query(filters, options) {
    const response = await frame.evaluate(([filters, options]) => window.napplet.outbox.query(filters, options), [filters, options]);
    calls.push({ filters, options, count: response.events.length, incomplete: response.incomplete, error: response.error });
    return response;
  } };
  const services = load('services', { './domain.js': load('domain'), '@napplet/sdk': { outbox } });
  const browse = await services.searchStations('');
  assert.ok(browse.stations.length >= 40, `Expected a populated Wavefunc directory; got ${browse.stations.length}`);
  assert.ok(browse.stations.every(s => s.name && s.name !== 'Untitled station' && s.streams.length));
  console.log(`PASS: browse returned ${browse.stations.length} named stations`);
  const search = await services.searchStations('idm');
  assert.ok(search.stations.some(s => s.name === 'IDM Ambient'));
  assert.ok(search.stations.some(s => s.name.includes('CliqHop')));
  console.log(`PASS: IDM search returned ${search.stations.length} stations; incomplete=${search.incomplete}`);
  const refs = browse.stations.slice(0, 2).map(s => s.address);
  const found = await services.readFavouriteStations(refs);
  assert.equal(found.stations.length, 2, 'Existing favourite addresses must resolve');
  console.log('PASS: two existing station addresses resolved through OUTBOX');
  if (owner) {
    const lists = await services.readFavourites(owner);
    for (const list of lists.lists) {
      const loaded = await services.readFavouriteStations(list.addresses.slice(0, 16));
      console.log(JSON.stringify({ list: list.name, requested: Math.min(list.addresses.length, 16), found: loaded.stations.length, incomplete: loaded.incomplete }));
    }
  }
  console.log(JSON.stringify({ host: url, calls }, null, 2));
} finally { await browser.close(); }