@reactivescript/runtime 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/web.js ADDED
@@ -0,0 +1,615 @@
1
+ // ../ref/compile/rt-web.ts
2
+ import { Portal as WebPortal } from "@solidjs/web";
3
+ import { getObserver } from "solid-js";
4
+ import {
5
+ createSignal,
6
+ createMemo,
7
+ createEffect,
8
+ createOptimistic,
9
+ createOptimisticStore,
10
+ createStore,
11
+ createProjection,
12
+ createDeferred,
13
+ createErrorBoundary,
14
+ createContext,
15
+ Errored,
16
+ createComponent,
17
+ flush,
18
+ untrack,
19
+ latest,
20
+ isPending,
21
+ action,
22
+ refresh,
23
+ affects,
24
+ until,
25
+ onSettled,
26
+ onFlush,
27
+ NotReadyError,
28
+ getOwner,
29
+ runWithOwner
30
+ } from "solid-js";
31
+ import { getContext, setContext, $TARGET } from "@solidjs/signals";
32
+ import { hydrate, render } from "@solidjs/web";
33
+ var readWhole = (v) => {
34
+ if (v !== null && typeof v === "object") Reflect.ownKeys(v);
35
+ return v;
36
+ };
37
+ var readCopy = (v) => v === null || typeof v !== "object" ? v : Array.isArray(v) ? v.map(readCopy) : Object.fromEntries(Object.keys(v).map((k) => [k, readCopy(v[k])]));
38
+ var latestWhole = (v) => v !== null && typeof v === "object" && v[$TARGET] !== void 0 ? readCopy(v) : v;
39
+ var sameInput = (a, b) => {
40
+ if (Object.is(a, b)) return true;
41
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
42
+ const pa = Object.getPrototypeOf(a), plain = (p) => p === Object.prototype || p === null || p === Array.prototype;
43
+ if (pa !== Object.getPrototypeOf(b) || !plain(pa)) return false;
44
+ const ka = Object.keys(a), kb = Object.keys(b);
45
+ return ka.length === kb.length && ka.every((k) => Object.prototype.hasOwnProperty.call(b, k) && sameInput(a[k], b[k]));
46
+ };
47
+ var ERR = { toString: () => "#error" };
48
+ var PENDING_MARK = { toString: () => "#pending" };
49
+ var fmt = (v) => v === ERR ? "#error" : v === PENDING_MARK ? "#pending" : v === void 0 ? "undefined" : typeof v === "string" ? v : JSON.stringify(v);
50
+ var raw = (x) => x && typeof x === "object" && x[$TARGET] ? x[$TARGET].v : x;
51
+ var isNode = (v) => typeof v === "function" || typeof v === "object" && v !== null && "nodeType" in v;
52
+ var isView = (v) => isNode(v) || Array.isArray(v) && (v.length === 0 || v.every((x) => x == null || typeof x === "string" || isView(x)) && v.some((x) => x != null && typeof x !== "string"));
53
+ function errorClass(name, params, message, id) {
54
+ const C = class extends Error {
55
+ constructor(...args) {
56
+ super("");
57
+ this.name = name;
58
+ params.forEach((p, i) => {
59
+ this[p] = args[i];
60
+ });
61
+ this.message = String(untrack(() => message(...args)));
62
+ if (id) this.$class = id;
63
+ }
64
+ };
65
+ Object.defineProperty(C, "name", { value: name });
66
+ Object.defineProperty(C, "declared", { value: true });
67
+ const f = ((...args) => new C(...args));
68
+ f.cls = C;
69
+ f.errorClass = name;
70
+ f.$class = id;
71
+ return f;
72
+ }
73
+ var PANIC = { panic: true };
74
+ var isA = (err, classes) => !classes || classes.includes(PANIC) || classes.some((c) => {
75
+ const k = c?.cls ?? c;
76
+ if (typeof k !== "function") return false;
77
+ if (err instanceof k) return true;
78
+ const id = c.$class;
79
+ if (id && err && typeof err === "object" && err.$class === id) {
80
+ Object.setPrototypeOf(err, k.prototype);
81
+ return true;
82
+ }
83
+ return false;
84
+ });
85
+ function catchAcc(f, match, alt) {
86
+ const acc = untrack(() => createErrorBoundary(() => readWhole(f()), (err) => new Fallback(() => {
87
+ const e0 = err();
88
+ return match(e0) ? alt(e0) : new Forward(e0);
89
+ })));
90
+ return () => unwrapFallback(acc());
91
+ }
92
+ function tryCatch(f, match, alt) {
93
+ try {
94
+ return f();
95
+ } catch (err) {
96
+ if (err instanceof NotReadyError || !match(err)) throw err;
97
+ return alt(err);
98
+ }
99
+ }
100
+ var Fallback = class {
101
+ get;
102
+ constructor(g) {
103
+ this.get = g;
104
+ }
105
+ };
106
+ function unwrapFallback(v0) {
107
+ let v = v0;
108
+ if (v instanceof Fallback) v = v.get();
109
+ if (v instanceof Forward) throw v.err;
110
+ return v;
111
+ }
112
+ var NO_PROVISION = {};
113
+ var Forward = class {
114
+ err;
115
+ constructor(e) {
116
+ this.err = e;
117
+ }
118
+ };
119
+ function wireCopy(v, where, fail) {
120
+ if (v === null || v === void 0 || typeof v === "string" || typeof v === "number" || typeof v === "boolean") return v;
121
+ if (Array.isArray(v)) return v.map((x, i) => wireCopy(x, `${where}[${i}]`, fail));
122
+ if (typeof v === "object") {
123
+ const proto = Object.getPrototypeOf(v);
124
+ if (proto === Object.prototype || proto === null) {
125
+ const o = {};
126
+ for (const k of Object.keys(v)) o[k] = wireCopy(v[k], `${where}.${k}`, fail);
127
+ return o;
128
+ }
129
+ }
130
+ return fail(`${where} is ${typeof v === "function" ? "a function" : `an instance of ${v.constructor?.name ?? "a class"}`}, which the wire cannot carry: send data`);
131
+ }
132
+ var wireFailure = (err) => err instanceof Error && err.constructor.declared ? err : new Error("Internal Server Error");
133
+ var Flight = class {
134
+ key;
135
+ first;
136
+ settleFirst;
137
+ rejectFirst;
138
+ queue = [];
139
+ waiters = [];
140
+ started = false;
141
+ constructor(key) {
142
+ this.key = key;
143
+ this.first = new Promise((r, j) => {
144
+ this.settleFirst = r;
145
+ this.rejectFirst = j;
146
+ });
147
+ this.first.catch(() => {
148
+ });
149
+ }
150
+ push(x) {
151
+ const w = this.waiters.shift();
152
+ if (w) w(x);
153
+ else this.queue.push(x);
154
+ }
155
+ resolve(v) {
156
+ if (!this.started) {
157
+ this.started = true;
158
+ this.settleFirst(v);
159
+ }
160
+ this.push({ v });
161
+ }
162
+ reject(e) {
163
+ if (!this.started) {
164
+ this.started = true;
165
+ this.rejectFirst(e);
166
+ }
167
+ this.push({ e });
168
+ }
169
+ [Symbol.asyncIterator]() {
170
+ const next = () => new Promise((res, rej) => {
171
+ const take = (x) => {
172
+ if ("e" in x) rej(x.e);
173
+ else res({ value: x.v, done: false });
174
+ };
175
+ const q = this.queue.shift();
176
+ if (q) take(q);
177
+ else this.waiters.push(take);
178
+ });
179
+ return { next, return: async () => ({ value: void 0, done: true }) };
180
+ }
181
+ };
182
+ function createApp(opts) {
183
+ const flights = /* @__PURE__ */ new Map();
184
+ const lastKey = /* @__PURE__ */ new Map();
185
+ const truthOf = /* @__PURE__ */ new Map();
186
+ const registry = /* @__PURE__ */ new Map();
187
+ const contexts = /* @__PURE__ */ new Map();
188
+ const storeAccs = /* @__PURE__ */ new WeakSet();
189
+ const modules = /* @__PURE__ */ new Map();
190
+ const hoistedBy = /* @__PURE__ */ new Map();
191
+ const hoistedOf = /* @__PURE__ */ new WeakMap();
192
+ const log = [];
193
+ let currentEq = null;
194
+ let serverSeq = 0;
195
+ let classSeq = 0;
196
+ const jsErrors = /* @__PURE__ */ new Map();
197
+ const tracing = () => {
198
+ let ran = false;
199
+ new Promise(() => {
200
+ ran = true;
201
+ });
202
+ return !ran;
203
+ };
204
+ const flight = (key) => {
205
+ if (tracing()) return new Flight(key);
206
+ let f = flights.get(key);
207
+ if (!f) {
208
+ f = new Flight(key);
209
+ flights.set(key, f);
210
+ }
211
+ if (currentEq) lastKey.set(currentEq, key);
212
+ return f;
213
+ };
214
+ const named = (name, fn) => name ? ((...a) => {
215
+ const was = currentEq;
216
+ currentEq = name;
217
+ try {
218
+ return fn(...a);
219
+ } finally {
220
+ currentEq = was;
221
+ }
222
+ }) : fn;
223
+ const app = {
224
+ root: opts.root,
225
+ log,
226
+ flights,
227
+ lastKey,
228
+ asyncError: null,
229
+ /** Mount `view` on the root: build it, or (SV-3) adopt the page the server streamed into it. */
230
+ mount(view, hydrating = false) {
231
+ return hydrating ? hydrate(view, app.root) : render(view, app.root);
232
+ },
233
+ // the prelude: what `import pure { … } from "./prelude"` and the built-in names refer to
234
+ B: {
235
+ len: (x) => Array.isArray(x) || typeof x === "string" ? x.length : typeof x === "object" && x ? Object.keys(x).length : 0,
236
+ str: (x) => fmt(x),
237
+ map: (xs, f) => xs.map(f),
238
+ filter: (xs, f) => xs.filter(f),
239
+ sum: (xs) => xs.reduce((a, b) => a + b, 0),
240
+ every: (xs, f) => xs.every(f),
241
+ indexOf: (xs, f) => xs.findIndex(f),
242
+ fail: (msg) => {
243
+ throw Object.assign(new Error(msg), { panic: true });
244
+ },
245
+ // R-f-3: a JS throw — a panic, not in the failure row
246
+ fetch: (key) => opts.api?.fetch ? opts.api.fetch(key) : flight(String(key)),
247
+ log: (...a) => {
248
+ log.push(`log(${a.map(fmt).join(", ")})`);
249
+ }
250
+ },
251
+ /** `import pure { f } from "./api"`: every function is a flight keyed by its name and formatted arguments. */
252
+ /** MO-8: a class `api.d.rx` declares as an error: the real module's, or (in the harness) a stand-in `C(message)`. */
253
+ jsError: (name) => jsErrors.get(name) ?? (jsErrors.set(name, opts.api?.[name] ?? errorClass(name, ["message"], (m) => m ?? name, `${name}#${classSeq++}`)), jsErrors.get(name)),
254
+ api: (name) => opts.api ? opts.api[name] ?? (() => {
255
+ throw new Error(`./api has no ${name}`);
256
+ }) : (...a) => flight(`${name}:${a.map(fmt).join(",")}`),
257
+ // ---- the scenario harness's view of names (handler rows reach any live binding by name) ----
258
+ reg(name, e) {
259
+ let l = registry.get(name);
260
+ if (!l) registry.set(name, l = []);
261
+ l.push(e);
262
+ const h = hoistedBy.get(name);
263
+ if (h && e.get) {
264
+ hoistedOf.set(e.get, h);
265
+ hoistedBy.delete(name);
266
+ }
267
+ },
268
+ lookup(name) {
269
+ const l = registry.get(name);
270
+ if (!l?.length) throw new Error(`unbound ${name}`);
271
+ for (let i = l.length - 1; i >= 0; i--) if (l[i].w) return l[i];
272
+ return l[l.length - 1];
273
+ },
274
+ dget(name, live = false) {
275
+ const e = app.lookup(name);
276
+ return e.get ? live ? e.get() : app.snapshot(e.get) : e.value;
277
+ },
278
+ // live: inside a probe (R-12), the read itself
279
+ dset(name, keys, v, guess = false) {
280
+ const w = app.lookup(name).w;
281
+ if (!w) throw new Error(`W-1: write to non-source ${name}`);
282
+ if (guess) w.guess(v, keys);
283
+ else if (keys.length) w.path(keys, v);
284
+ else w.set(v);
285
+ },
286
+ // ---- declarations ----
287
+ /** `source x := e`: atomic → a signal; structured → a store behind a signal slot, so the root can be replaced (ST-1, ST-2a). */
288
+ source(name, init) {
289
+ void name;
290
+ if (typeof init === "object" && init !== null) {
291
+ const [store, setStore] = createStore(init);
292
+ const [get2, set2] = createSignal(store);
293
+ const w = {
294
+ set: (v) => {
295
+ if (typeof v === "function") {
296
+ setStore(v);
297
+ set2(store);
298
+ } else if (typeof v === "object" && v !== null) {
299
+ setStore(() => v);
300
+ set2(store);
301
+ } else set2(v);
302
+ },
303
+ path: (keys, v) => setStore((d) => {
304
+ let o = d;
305
+ for (const k of keys.slice(0, -1)) o = o[k];
306
+ o[keys[keys.length - 1]] = v;
307
+ }),
308
+ guess: () => {
309
+ throw new Error("OPTIMISTIC_NO_QUESTION");
310
+ }
311
+ };
312
+ return [get2, w];
313
+ }
314
+ const [get, set] = createSignal(init);
315
+ return [get, { set, path: () => {
316
+ throw new Error("a path write to an atomic source");
317
+ }, guess: () => {
318
+ throw new Error("OPTIMISTIC_NO_QUESTION");
319
+ } }];
320
+ },
321
+ /** `source x = e` (ST-5): createSignal(fn); with a guess written to it, a createOptimistic layer over that truth (AC-3);
322
+ * written or probed by path, createStore(fn, {}) whose derive writes its draft. */
323
+ question(name, compute, opts2, mode, key) {
324
+ const fn = named(name, compute);
325
+ if (mode.optimistic && mode.structured) {
326
+ const [store, setStore] = createOptimisticStore((draft) => {
327
+ const r = fn(draft);
328
+ if (r instanceof Flight || r instanceof Promise) return (async () => assignDraft(draft, r instanceof Flight ? await r.first : await r))();
329
+ assignDraft(draft, r);
330
+ }, key ? [] : {}, key ? { key } : void 0);
331
+ const get2 = () => store;
332
+ storeAccs.add(get2);
333
+ const plain = () => {
334
+ throw new Error("a plain write to an optimistic store is not lowered yet");
335
+ };
336
+ return [get2, { set: plain, path: plain, guess: (v, keys = []) => setStore((d) => {
337
+ if (keys.length === 0) {
338
+ assignDraft(d, typeof v === "function" ? v(d) : v);
339
+ return;
340
+ }
341
+ let o = d;
342
+ for (const k of keys.slice(0, -1)) o = o[k];
343
+ const last = keys[keys.length - 1];
344
+ o[last] = typeof v === "function" ? v(o[last]) : v;
345
+ }) }];
346
+ }
347
+ if (mode.optimistic) {
348
+ const [truth, setTruth] = createSignal(fn, opts2);
349
+ const [get2, setGuess] = createOptimistic(() => truth());
350
+ truthOf.set(get2, truth);
351
+ return [get2, { set: setTruth, path: () => {
352
+ throw new Error("optimistic path writes are not lowered yet");
353
+ }, guess: setGuess }];
354
+ }
355
+ if (mode.structured) {
356
+ const [store, setStore] = createStore(async (draft) => {
357
+ const r = fn(draft);
358
+ const v = r instanceof Flight ? await r.first : await r;
359
+ if (v && typeof v === "object") {
360
+ for (const k of Object.keys(draft)) if (!(k in v)) delete draft[k];
361
+ Object.assign(draft, v);
362
+ }
363
+ }, {});
364
+ const get2 = () => store;
365
+ storeAccs.add(get2);
366
+ return [get2, { set: () => {
367
+ throw new Error("a root write to a derived store is not lowered yet");
368
+ }, path: (keys, v) => setStore((d) => {
369
+ let o = d;
370
+ for (const k of keys.slice(0, -1)) o = o[k];
371
+ o[keys[keys.length - 1]] = v;
372
+ }), guess: () => {
373
+ throw new Error("optimistic over a structured question source is not lowered yet");
374
+ } }];
375
+ }
376
+ const [get, set] = createSignal(fn, opts2);
377
+ return [get, { set, path: () => {
378
+ throw new Error("a path write to an atomic source");
379
+ }, guess: () => {
380
+ throw new Error("OPTIMISTIC_NO_QUESTION");
381
+ } }];
382
+ },
383
+ memo: (name, fn, opts2) => createMemo(named(name, fn), opts2),
384
+ deferred: (name, fn, opts2) => createDeferred(named(name, fn), opts2),
385
+ /** `x key k = e` (ST-4): a keyed projection. */
386
+ keyed: (name, key, fn) => {
387
+ const src = createMemo(named(name, () => fn()));
388
+ const p = createProjection(() => src(), [], { key });
389
+ return () => p;
390
+ },
391
+ // the answer is a memo (sync, or the tail await's); the projection reconciles it by key
392
+ /** `x = draft(pre x -> seed) { … }` (ST-3). */
393
+ draft: (seed, body) => {
394
+ const p = createProjection(body, seed);
395
+ return () => p;
396
+ },
397
+ /** `pre y` of another node (C-2): a companion memo carrying (current, previous), owned where `y` is declared. */
398
+ pre: (get) => {
399
+ const m = createMemo((st) => ({ cur: get(), prev: st ? st.cur : void 0 }));
400
+ return () => m().prev;
401
+ },
402
+ firstPaint: (f) => ({ loadingValue: untrack(f) }),
403
+ /** `effect (…) { … }`: compute, then apply; an error is an answer the apply receives (E-12); fires on a differing value (EF-2); a store enters whole, as a snapshot. */
404
+ effect(n, inputs, apply) {
405
+ const run = (vals) => {
406
+ const r = apply(vals);
407
+ return typeof r === "function" ? r : void 0;
408
+ };
409
+ let last = null;
410
+ createEffect((() => inputs().map(latestWhole)), { effect: (vals) => {
411
+ if (last && last.length === vals.length && vals.every((v, i) => sameInput(v, last[i]))) return;
412
+ last = vals;
413
+ return run(vals);
414
+ }, error: () => {
415
+ last = null;
416
+ return run(Array.from({ length: n }, () => ERR));
417
+ } });
418
+ },
419
+ /** `action f(…) { … }` (AC-1): a generator; a statement-level `await` is a hold-safe yield. */
420
+ action(gen) {
421
+ const run = action(gen);
422
+ return (...a) => {
423
+ const p = run(...a);
424
+ p.catch((e) => {
425
+ app.asyncError = e;
426
+ });
427
+ return p;
428
+ };
429
+ },
430
+ awaited: (v) => v instanceof Flight ? v.first : v,
431
+ /** RG-8: Solid's Portal — client-only: the server renders nothing for it, the browser renders it once it has the page. */
432
+ Portal: WebPortal,
433
+ /** CSS-2: a dynamic class with the view's scope class after it. */
434
+ scopedClass: (v, hash) => v == null || v === false || v === "" ? hash : `${v} ${hash}`,
435
+ /** SV-7b: a client question — not asked on the server; the browser asks it once hydrated (Solid's \`ssrSource: "client"\`). */
436
+ clientQuestion: (o) => ({ ...o ?? {}, ssrSource: "client" }),
437
+ /** 12 SF-2: a server fn as the client calls it — every call a flight. Asked in reactive scope it is a question, one
438
+ * flight per arguments, as a JS import's; in imperative scope each call is a new request. \`fn\` is the module-level
439
+ * \`"use server"\` function (SF-7a): the body in place, or — once Solid's \`transformDirectives\` has made it a reference
440
+ * — a request to the server. */
441
+ serverRef(name, fn) {
442
+ return (...args) => {
443
+ const key = `${name}:${args.map(fmt).join(",")}`;
444
+ const question = !!getObserver();
445
+ if (question && flights.has(key)) return flights.get(key);
446
+ const fl = question ? flight(key) : new Flight(`${key}#${serverSeq++}`);
447
+ globalThis.__rx_app = app;
448
+ let p;
449
+ try {
450
+ p = Promise.resolve(fn(...args));
451
+ } catch (e) {
452
+ p = Promise.reject(e);
453
+ }
454
+ p.then((v) => fl.resolve(v), (e) => fl.reject(e));
455
+ return fl;
456
+ };
457
+ },
458
+ /** SF-6: a server fn's body (a generator, as an action's), driven by promises — not by an action: it is no change of
459
+ * the client's — behind a wire that copies arguments and result and lets only declared failures through. */
460
+ serverCall(name, gen, args) {
461
+ return new Promise((resolve, reject) => {
462
+ const fail = (msg) => {
463
+ throw new Error(`WIRE_VALUE: ${name}: ${msg}`);
464
+ };
465
+ let g;
466
+ try {
467
+ g = gen(...args.map((a, i) => wireCopy(a, `argument ${i + 1}`, fail)));
468
+ } catch (e) {
469
+ reject(e);
470
+ return;
471
+ }
472
+ const step = (input, thrown) => {
473
+ const was = currentEq;
474
+ currentEq = null;
475
+ let r;
476
+ try {
477
+ r = untrack(() => thrown ? g.throw(input) : g.next(input));
478
+ } catch (e) {
479
+ reject(wireFailure(e));
480
+ return;
481
+ } finally {
482
+ currentEq = was;
483
+ }
484
+ if (r.done) {
485
+ try {
486
+ resolve(wireCopy(r.value, "its result", fail));
487
+ } catch (e) {
488
+ reject(e);
489
+ }
490
+ return;
491
+ }
492
+ Promise.resolve(r.value).then((v) => step(v, false), (e) => step(e, true));
493
+ };
494
+ step(void 0, false);
495
+ });
496
+ },
497
+ hoisted(name, get) {
498
+ let l = hoistedBy.get(name);
499
+ if (!l) hoistedBy.set(name, l = []);
500
+ l.push(get);
501
+ },
502
+ until: (p) => until(p),
503
+ // AC-6
504
+ onSettled: (f) => onSettled(f),
505
+ // EF-7
506
+ onFlush: (f) => onFlush(f),
507
+ // EF-8
508
+ refresh(name, get) {
509
+ const key = lastKey.get(name);
510
+ if (key) flights.delete(key);
511
+ for (const h of hoistedOf.get(get) ?? []) refresh(h);
512
+ const t = truthOf.get(get) ?? get;
513
+ refresh(storeAccs.has(t) ? t() : t);
514
+ },
515
+ affects: (get) => affects(get),
516
+ preOr: (v, init) => v === void 0 ? init() : v,
517
+ // ---- modules (09 MO-1): a dependency's factory runs once per app; its exports are shared by every importer ----
518
+ module(key, factory) {
519
+ let m = modules.get(key);
520
+ if (!m) {
521
+ m = factory(app);
522
+ modules.set(key, m);
523
+ }
524
+ return m;
525
+ },
526
+ // ---- context (RG-7) ----
527
+ owner: () => getOwner(),
528
+ /** `context x: T = d` (RG-7): the declaration is the identity; `d`, if any, is evaluated once, owned where it is declared. */
529
+ /** `context x: T = d` (RG-7): the declaration is the identity (a sentinel default: absence is ours to decide); `d` is
530
+ * evaluated once, owned where it is declared — created now, so it takes its id there on both sides (SV-3). */
531
+ context(name, dflt) {
532
+ return { name, ctx: createContext(NO_PROVISION, name), dflt, owner: getOwner(), dv: dflt ? { get: createMemo(dflt) } : null };
533
+ },
534
+ provide(c, e) {
535
+ setContext(c.ctx, e);
536
+ },
537
+ use(c, owner) {
538
+ const e = getContext(c.ctx, owner ?? void 0);
539
+ if (e && e !== NO_PROVISION) return e;
540
+ if (c.dv) return c.dv;
541
+ throw new Error(`RG-7b: no provision for ${c.name}`);
542
+ },
543
+ useGet(c, owner) {
544
+ const e = app.use(c, owner);
545
+ return e.get ? e.get() : e.value;
546
+ },
547
+ runWithOwner,
548
+ // ---- reads ----
549
+ /** An imperative read sees σ (H-10): a pending value is a value; a snapshot of an error throws it (R-f-7). */
550
+ snapshot(get) {
551
+ try {
552
+ return untrack(get);
553
+ } catch (e) {
554
+ if (e instanceof NotReadyError) return PENDING_MARK;
555
+ throw e;
556
+ }
557
+ },
558
+ // ---- failures (R-f) ----
559
+ errorClass: (name, params, message) => errorClass(name, params, message, `${name}#${classSeq++}`),
560
+ // a declaration's identity: the same on both sides (SV-5a)
561
+ isA,
562
+ PANIC,
563
+ catchMemo: catchAcc,
564
+ tryCatch,
565
+ catchRead: (f, match, alt) => catchAcc(f, match, alt)(),
566
+ throw: (e) => {
567
+ throw e;
568
+ },
569
+ eq: (a, b) => raw(a) === raw(b),
570
+ untrack,
571
+ latest: (f) => latest(() => latestWhole(f())),
572
+ isPending: (f) => isPending(() => readWhole(f())),
573
+ fmt,
574
+ // ---- views: compiled JSX (compile/jsx.ts, generate "dom") does the rest ----
575
+ show: (v) => isView(v) ? v : fmt(v),
576
+ /** `errored fallback(e: A | B)`: a failure of another class passes to the boundary above (R-f-4) — the fallback hands it out
577
+ * and a memo throws it there (a rethrow from the fallback itself did not recover until solidjs/solid#4277: ref/oracle/repros/dv7-rethrow.mjs). */
578
+ TypedErrored(props) {
579
+ const classes = props.classes;
580
+ const out = createComponent(Errored, {
581
+ fallback: (err) => {
582
+ const owner = getOwner();
583
+ const ok = createMemo(() => isA(err(), classes));
584
+ let shown = null;
585
+ return new Fallback(() => ok() ? shown ??= runWithOwner(owner, () => props.fallback(err)) : new Forward(err()));
586
+ },
587
+ get children() {
588
+ return props.children;
589
+ }
590
+ });
591
+ return createMemo(() => unwrapFallback(typeof out === "function" ? out() : out));
592
+ }
593
+ };
594
+ return app;
595
+ }
596
+ function assignDraft(draft, v) {
597
+ if (!v || typeof v !== "object") return;
598
+ if (Array.isArray(draft) && Array.isArray(v)) {
599
+ draft.length = v.length;
600
+ v.forEach((x, i) => {
601
+ draft[i] = x;
602
+ });
603
+ return;
604
+ }
605
+ for (const k of Object.keys(draft)) if (!(k in v)) delete draft[k];
606
+ Object.assign(draft, v);
607
+ }
608
+ export {
609
+ ERR,
610
+ Flight,
611
+ PENDING_MARK,
612
+ createApp,
613
+ flush,
614
+ fmt
615
+ };
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "name": "@reactivescript/runtime",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "description": "ReactiveScript's runtime (spec/11 CP-4a): createApp and the __rt helpers compiled .rx calls, over Solid, for the browser and the server",
4
+ "version": "0.1.0",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/solidjs/reactivescript.git",
9
+ "directory": "runtime"
10
+ },
11
+ "type": "module",
12
+ "sideEffects": false,
13
+ "exports": {
14
+ ".": {
15
+ "worker": {
16
+ "types": "./dist/server.d.ts",
17
+ "default": "./dist/server.js"
18
+ },
19
+ "browser": {
20
+ "types": "./dist/web.d.ts",
21
+ "default": "./dist/web.js"
22
+ },
23
+ "deno": {
24
+ "types": "./dist/server.d.ts",
25
+ "default": "./dist/server.js"
26
+ },
27
+ "node": {
28
+ "types": "./dist/server.d.ts",
29
+ "default": "./dist/server.js"
30
+ },
31
+ "types": "./dist/web.d.ts",
32
+ "default": "./dist/web.js"
33
+ },
34
+ "./web": {
35
+ "types": "./dist/web.d.ts",
36
+ "default": "./dist/web.js"
37
+ },
38
+ "./server": {
39
+ "types": "./dist/server.d.ts",
40
+ "default": "./dist/server.js"
41
+ }
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "README.md"
46
+ ],
47
+ "scripts": {
48
+ "build": "node build.mjs",
49
+ "prepack": "node build.mjs",
50
+ "test": "node test.mjs"
51
+ },
52
+ "peerDependencies": {
53
+ "@solidjs/signals": "^2.0.0-rc.21",
54
+ "@solidjs/web": "^2.0.0-rc.21",
55
+ "solid-js": "^2.0.0-rc.21"
56
+ },
57
+ "devDependencies": {
58
+ "@solidjs/signals": "2.0.0-rc.21",
59
+ "@solidjs/web": "2.0.0-rc.21",
60
+ "esbuild": "^0.28.2",
61
+ "solid-js": "2.0.0-rc.21",
62
+ "typescript": "^6.0.3"
63
+ }
64
+ }