solid-js 2.0.0-experimental.14 → 2.0.0-experimental.15

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/solid.js CHANGED
@@ -1,5 +1,5 @@
1
- import { getContext, createMemo as createMemo$1, flatten, createRoot, setContext, getOwner, getNextChildId, createSignal as createSignal$1, createLoadBoundary, flush, runWithOwner, untrack, mapArray, repeat, createErrorBoundary } from '@solidjs/signals';
2
- export { $PROXY, $TRACK, NotReadyError, action, createEffect, createOptimistic, createOptimisticStore, createProjection, createReaction, createRenderEffect, createRoot, createStore, createTrackedEffect, deep, flatten, flush, getObserver, getOwner, isEqual, isPending, isRefreshing, isWrappable, mapArray, merge, omit, onCleanup, onSettled, pending, reconcile, refresh, repeat, resolve, runWithOwner, snapshot, untrack } from '@solidjs/signals';
1
+ import { getContext, createMemo as createMemo$1, flatten, createRoot, setContext, createLoadBoundary, getOwner, onCleanup, isDisposed, runWithOwner, createOptimistic as createOptimistic$1, createOptimisticStore as createOptimisticStore$1, createProjection as createProjection$1, createSignal as createSignal$1, createStore as createStore$1, setSnapshotCapture, releaseSnapshotScope, getNextChildId, createErrorBoundary as createErrorBoundary$1, markSnapshotScope, flush, clearSnapshots, peekNextChildId, untrack, mapArray, repeat } from '@solidjs/signals';
2
+ export { $PROXY, $TRACK, NotReadyError, action, createEffect, createReaction, createRenderEffect, createRoot, createTrackedEffect, deep, flatten, flush, getObserver, getOwner, isEqual, isPending, isRefreshing, isWrappable, mapArray, merge, omit, onCleanup, onSettled, pending, reconcile, refresh, repeat, resolve, runWithOwner, snapshot, untrack } from '@solidjs/signals';
3
3
 
4
4
  const $DEVCOMP = Symbol(0);
5
5
  function createContext(defaultValue, options) {
@@ -37,8 +37,44 @@ const sharedConfig = {
37
37
  return getNextChildId(o);
38
38
  }
39
39
  };
40
+ let _hydrationEndCallbacks = null;
41
+ let _pendingBoundaries = 0;
42
+ let _hydrationDone = false;
43
+ let _snapshotRootOwner = null;
44
+ function markTopLevelSnapshotScope() {
45
+ if (_snapshotRootOwner) return;
46
+ let owner = getOwner();
47
+ if (!owner) return;
48
+ while (owner._parent) owner = owner._parent;
49
+ markSnapshotScope(owner);
50
+ _snapshotRootOwner = owner;
51
+ }
52
+ function drainHydrationCallbacks() {
53
+ if (_hydrationDone) return;
54
+ _hydrationDone = true;
55
+ _doneValue = true;
56
+ clearSnapshots();
57
+ setSnapshotCapture(false);
58
+ flush();
59
+ const cbs = _hydrationEndCallbacks;
60
+ _hydrationEndCallbacks = null;
61
+ if (cbs) for (const cb of cbs) cb();
62
+ setTimeout(() => {
63
+ if (globalThis._$HY) globalThis._$HY.done = true;
64
+ });
65
+ }
66
+ function checkHydrationComplete() {
67
+ if (_pendingBoundaries === 0) drainHydrationCallbacks();
68
+ }
69
+ let _hydratingValue = false;
70
+ let _doneValue = false;
40
71
  let _createMemo;
41
72
  let _createSignal;
73
+ let _createErrorBoundary;
74
+ let _createOptimistic;
75
+ let _createProjection;
76
+ let _createStore;
77
+ let _createOptimisticStore;
42
78
  class MockPromise {
43
79
  static all() {
44
80
  return new MockPromise();
@@ -74,14 +110,110 @@ function subFetch(fn, prev) {
74
110
  try {
75
111
  window.fetch = () => new MockPromise();
76
112
  Promise = MockPromise;
77
- return fn(prev);
113
+ const result = fn(prev);
114
+ if (result && typeof result[Symbol.asyncIterator] === "function") {
115
+ result[Symbol.asyncIterator]().next();
116
+ }
117
+ return result;
78
118
  } finally {
79
119
  window.fetch = ogFetch;
80
120
  Promise = ogPromise;
81
121
  }
82
122
  }
123
+ function consumeFirstSync(ai) {
124
+ const iter = ai[Symbol.asyncIterator]();
125
+ const r = iter.next();
126
+ const value = !(r instanceof Promise) && !r.done ? r.value : undefined;
127
+ return [value, iter];
128
+ }
129
+ function applyPatches(target, patches) {
130
+ for (const patch of patches) {
131
+ const path = patch[0];
132
+ let current = target;
133
+ for (let i = 0; i < path.length - 1; i++) current = current[path[i]];
134
+ const key = path[path.length - 1];
135
+ if (patch.length === 1) {
136
+ Array.isArray(current) ? current.splice(key, 1) : delete current[key];
137
+ } else if (patch.length === 3) {
138
+ current.splice(key, 0, patch[1]);
139
+ } else {
140
+ current[key] = patch[1];
141
+ }
142
+ }
143
+ }
144
+ function scheduleIteratorConsumption(iter, apply) {
145
+ const consume = () => {
146
+ while (true) {
147
+ const n = iter.next();
148
+ if (n instanceof Promise) {
149
+ n.then(r => {
150
+ if (r.done) return;
151
+ apply(r.value);
152
+ consume();
153
+ });
154
+ return;
155
+ }
156
+ if (n.done) break;
157
+ apply(n.value);
158
+ }
159
+ };
160
+ consume();
161
+ }
162
+ function isAsyncIterable(v) {
163
+ return v != null && typeof v[Symbol.asyncIterator] === "function";
164
+ }
165
+ function hydrateSignalFromAsyncIterable(coreFn, compute, value, options) {
166
+ const parent = getOwner();
167
+ const expectedId = peekNextChildId(parent);
168
+ if (!sharedConfig.has(expectedId)) return null;
169
+ const initP = sharedConfig.load(expectedId);
170
+ if (!isAsyncIterable(initP)) return null;
171
+ const [firstValue, iter] = consumeFirstSync(initP);
172
+ const [get, set] = createSignal$1(firstValue);
173
+ const result = coreFn(() => get(), firstValue, options);
174
+ scheduleIteratorConsumption(iter, v => {
175
+ set(() => v);
176
+ flush();
177
+ });
178
+ return result;
179
+ }
180
+ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
181
+ const parent = getOwner();
182
+ const expectedId = peekNextChildId(parent);
183
+ if (!sharedConfig.has(expectedId)) return null;
184
+ const initP = sharedConfig.load(expectedId);
185
+ if (!isAsyncIterable(initP)) return null;
186
+ const [firstState, iter] = consumeFirstSync(initP);
187
+ const [store, setStore] = coreFn(() => {}, firstState ?? initialValue, options);
188
+ scheduleIteratorConsumption(iter, patches => {
189
+ setStore(d => {
190
+ applyPatches(d, patches);
191
+ });
192
+ });
193
+ return [store, setStore];
194
+ }
83
195
  function hydratedCreateMemo(compute, value, options) {
84
196
  if (!sharedConfig.hydrating) return createMemo$1(compute, value, options);
197
+ markTopLevelSnapshotScope();
198
+ const ssrSource = options?.ssrSource;
199
+ if (ssrSource === "client") {
200
+ const [hydrated, setHydrated] = createSignal$1(false);
201
+ const memo = createMemo$1(prev => {
202
+ if (!hydrated()) return prev ?? value;
203
+ return compute(prev);
204
+ }, value, options);
205
+ setHydrated(true);
206
+ return memo;
207
+ }
208
+ if (ssrSource === "initial") {
209
+ return createMemo$1(prev => {
210
+ if (!sharedConfig.hydrating) return compute(prev);
211
+ subFetch(compute, prev);
212
+ return prev ?? value;
213
+ }, value, options);
214
+ }
215
+ const aiResult = hydrateSignalFromAsyncIterable(createMemo$1, compute, value, options);
216
+ if (aiResult !== null) return aiResult;
85
217
  return createMemo$1(prev => {
86
218
  const o = getOwner();
87
219
  if (!sharedConfig.hydrating) return compute(prev);
@@ -93,6 +225,26 @@ function hydratedCreateMemo(compute, value, options) {
93
225
  }
94
226
  function hydratedCreateSignal(fn, second, third) {
95
227
  if (typeof fn !== "function" || !sharedConfig.hydrating) return createSignal$1(fn, second, third);
228
+ markTopLevelSnapshotScope();
229
+ const ssrSource = third?.ssrSource;
230
+ if (ssrSource === "client") {
231
+ const [hydrated, setHydrated] = createSignal$1(false);
232
+ const sig = createSignal$1(prev => {
233
+ if (!hydrated()) return prev ?? second;
234
+ return fn(prev);
235
+ }, second, third);
236
+ setHydrated(true);
237
+ return sig;
238
+ }
239
+ if (ssrSource === "initial") {
240
+ return createSignal$1(prev => {
241
+ if (!sharedConfig.hydrating) return fn(prev);
242
+ subFetch(fn, prev);
243
+ return prev ?? second;
244
+ }, second, third);
245
+ }
246
+ const aiResult = hydrateSignalFromAsyncIterable(createSignal$1, fn, second, third);
247
+ if (aiResult !== null) return aiResult;
96
248
  return createSignal$1(prev => {
97
249
  if (!sharedConfig.hydrating) return fn(prev);
98
250
  const o = getOwner();
@@ -102,17 +254,215 @@ function hydratedCreateSignal(fn, second, third) {
102
254
  return init != null ? (subFetch(fn, prev), init) : fn(prev);
103
255
  }, second, third);
104
256
  }
257
+ function hydratedCreateErrorBoundary(fn, fallback) {
258
+ if (!sharedConfig.hydrating) return createErrorBoundary$1(fn, fallback);
259
+ markTopLevelSnapshotScope();
260
+ const parent = getOwner();
261
+ const expectedId = peekNextChildId(parent);
262
+ if (sharedConfig.has(expectedId)) {
263
+ const err = sharedConfig.load(expectedId);
264
+ if (err !== undefined) {
265
+ let hydrated = true;
266
+ return createErrorBoundary$1(() => {
267
+ if (hydrated) {
268
+ hydrated = false;
269
+ throw err;
270
+ }
271
+ return fn();
272
+ }, fallback);
273
+ }
274
+ }
275
+ return createErrorBoundary$1(fn, fallback);
276
+ }
277
+ function hydratedCreateOptimistic(fn, second, third) {
278
+ if (typeof fn !== "function" || !sharedConfig.hydrating) return createOptimistic$1(fn, second, third);
279
+ markTopLevelSnapshotScope();
280
+ const ssrSource = third?.ssrSource;
281
+ if (ssrSource === "client") {
282
+ const [hydrated, setHydrated] = createSignal$1(false);
283
+ const sig = createOptimistic$1(prev => {
284
+ if (!hydrated()) return prev ?? second;
285
+ return fn(prev);
286
+ }, second, third);
287
+ setHydrated(true);
288
+ return sig;
289
+ }
290
+ if (ssrSource === "initial") {
291
+ return createOptimistic$1(prev => {
292
+ if (!sharedConfig.hydrating) return fn(prev);
293
+ subFetch(fn, prev);
294
+ return prev ?? second;
295
+ }, second, third);
296
+ }
297
+ const aiResult = hydrateSignalFromAsyncIterable(createOptimistic$1, fn, second, third);
298
+ if (aiResult !== null) return aiResult;
299
+ return createOptimistic$1(prev => {
300
+ const o = getOwner();
301
+ if (!sharedConfig.hydrating) return fn(prev);
302
+ let initP;
303
+ if (sharedConfig.has(o.id)) initP = sharedConfig.load(o.id);
304
+ const init = initP?.v ?? initP;
305
+ return init != null ? (subFetch(fn, prev), init) : fn(prev);
306
+ }, second, third);
307
+ }
308
+ function wrapStoreFn(fn, ssrSource) {
309
+ if (ssrSource === "initial") {
310
+ return draft => {
311
+ if (!sharedConfig.hydrating) return fn(draft);
312
+ subFetch(fn, draft);
313
+ return undefined;
314
+ };
315
+ }
316
+ return draft => {
317
+ const o = getOwner();
318
+ if (!sharedConfig.hydrating) return fn(draft);
319
+ let initP;
320
+ if (sharedConfig.has(o.id)) initP = sharedConfig.load(o.id);
321
+ const init = initP?.v ?? initP;
322
+ return init != null ? (subFetch(fn, draft), init) : fn(draft);
323
+ };
324
+ }
325
+ function hydratedCreateStore(first, second, third) {
326
+ if (typeof first !== "function" || !sharedConfig.hydrating) return createStore$1(first, second, third);
327
+ markTopLevelSnapshotScope();
328
+ const ssrSource = third?.ssrSource;
329
+ if (ssrSource === "client" || ssrSource === "initial") {
330
+ return createStore$1(second ?? {}, undefined, third);
331
+ }
332
+ const aiResult = hydrateStoreFromAsyncIterable(createStore$1, second ?? {}, third);
333
+ if (aiResult !== null) return aiResult;
334
+ return createStore$1(wrapStoreFn(first, ssrSource), second, third);
335
+ }
336
+ function hydratedCreateOptimisticStore(first, second, third) {
337
+ if (typeof first !== "function" || !sharedConfig.hydrating) return createOptimisticStore$1(first, second, third);
338
+ markTopLevelSnapshotScope();
339
+ const ssrSource = third?.ssrSource;
340
+ if (ssrSource === "client" || ssrSource === "initial") {
341
+ return createOptimisticStore$1(second ?? {}, undefined, third);
342
+ }
343
+ const aiResult = hydrateStoreFromAsyncIterable(createOptimisticStore$1, second ?? {}, third);
344
+ if (aiResult !== null) return aiResult;
345
+ return createOptimisticStore$1(wrapStoreFn(first, ssrSource), second, third);
346
+ }
347
+ function hydratedCreateProjection(fn, initialValue, options) {
348
+ if (!sharedConfig.hydrating) return createProjection$1(fn, initialValue, options);
349
+ markTopLevelSnapshotScope();
350
+ const ssrSource = options?.ssrSource;
351
+ if (ssrSource === "client" || ssrSource === "initial") {
352
+ return createProjection$1(draft => draft, initialValue, options);
353
+ }
354
+ const aiResult = hydrateStoreFromAsyncIterable(createStore$1, initialValue, options);
355
+ if (aiResult !== null) return aiResult[0];
356
+ return createProjection$1(wrapStoreFn(fn, ssrSource), initialValue, options);
357
+ }
105
358
  function enableHydration() {
106
359
  _createMemo = hydratedCreateMemo;
107
360
  _createSignal = hydratedCreateSignal;
361
+ _createErrorBoundary = hydratedCreateErrorBoundary;
362
+ _createOptimistic = hydratedCreateOptimistic;
363
+ _createProjection = hydratedCreateProjection;
364
+ _createStore = hydratedCreateStore;
365
+ _createOptimisticStore = hydratedCreateOptimisticStore;
366
+ _hydratingValue = sharedConfig.hydrating;
367
+ _doneValue = sharedConfig.done;
368
+ Object.defineProperty(sharedConfig, "hydrating", {
369
+ get() {
370
+ return _hydratingValue;
371
+ },
372
+ set(v) {
373
+ const was = _hydratingValue;
374
+ _hydratingValue = v;
375
+ if (!was && v) {
376
+ _hydrationDone = false;
377
+ _doneValue = false;
378
+ _pendingBoundaries = 0;
379
+ setSnapshotCapture(true);
380
+ _snapshotRootOwner = null;
381
+ } else if (was && !v) {
382
+ if (_snapshotRootOwner) {
383
+ releaseSnapshotScope(_snapshotRootOwner);
384
+ _snapshotRootOwner = null;
385
+ }
386
+ checkHydrationComplete();
387
+ }
388
+ },
389
+ configurable: true,
390
+ enumerable: true
391
+ });
392
+ Object.defineProperty(sharedConfig, "done", {
393
+ get() {
394
+ return _doneValue;
395
+ },
396
+ set(v) {
397
+ _doneValue = v;
398
+ if (v) drainHydrationCallbacks();
399
+ },
400
+ configurable: true,
401
+ enumerable: true
402
+ });
108
403
  }
109
404
  const createMemo = (...args) => (_createMemo || createMemo$1)(...args);
110
405
  const createSignal = (...args) => (_createSignal || createSignal$1)(...args);
406
+ const createErrorBoundary = (...args) => (_createErrorBoundary || createErrorBoundary$1)(...args);
407
+ const createOptimistic = (...args) => (_createOptimistic || createOptimistic$1)(...args);
408
+ const createProjection = (...args) => (_createProjection || createProjection$1)(...args);
409
+ const createStore = (...args) => (_createStore || createStore$1)(...args);
410
+ const createOptimisticStore = (...args) => (_createOptimisticStore || createOptimisticStore$1)(...args);
411
+ function loadModuleAssets(mapping) {
412
+ const hy = globalThis._$HY;
413
+ if (!hy) return;
414
+ if (!hy.modules) hy.modules = {};
415
+ if (!hy.loading) hy.loading = {};
416
+ const pending = [];
417
+ for (const moduleUrl in mapping) {
418
+ if (hy.modules[moduleUrl]) continue;
419
+ const entryUrl = mapping[moduleUrl];
420
+ if (!hy.loading[moduleUrl]) {
421
+ hy.loading[moduleUrl] = import(entryUrl).then(mod => {
422
+ hy.modules[moduleUrl] = mod;
423
+ });
424
+ }
425
+ pending.push(hy.loading[moduleUrl]);
426
+ }
427
+ return pending.length ? Promise.all(pending).then(() => {}) : undefined;
428
+ }
429
+ function createBoundaryTrigger() {
430
+ setSnapshotCapture(false);
431
+ const [s, set] = createSignal$1(undefined, {
432
+ equals: false
433
+ });
434
+ s();
435
+ setSnapshotCapture(true);
436
+ return set;
437
+ }
438
+ function resumeBoundaryHydration(o, id, set) {
439
+ _pendingBoundaries--;
440
+ if (isDisposed(o)) {
441
+ checkHydrationComplete();
442
+ return;
443
+ }
444
+ sharedConfig.gather(id);
445
+ _hydratingValue = true;
446
+ markSnapshotScope(o);
447
+ _snapshotRootOwner = o;
448
+ set();
449
+ flush();
450
+ _snapshotRootOwner = null;
451
+ _hydratingValue = false;
452
+ releaseSnapshotScope(o);
453
+ flush();
454
+ checkHydrationComplete();
455
+ }
111
456
  function Loading(props) {
112
457
  if (!sharedConfig.hydrating) return createLoadBoundary(() => props.children, () => props.fallback);
113
458
  return createMemo$1(() => {
114
459
  const o = getOwner();
115
460
  const id = o.id;
461
+ let assetPromise;
462
+ if (sharedConfig.hydrating && sharedConfig.has(id + "_assets")) {
463
+ const mapping = sharedConfig.load(id + "_assets");
464
+ if (mapping && typeof mapping === "object") assetPromise = loadModuleAssets(mapping);
465
+ }
116
466
  if (sharedConfig.hydrating && sharedConfig.has(id)) {
117
467
  let ref = sharedConfig.load(id);
118
468
  let p;
@@ -120,24 +470,38 @@ function Loading(props) {
120
470
  if (typeof ref !== "object" || ref.s !== 1) p = ref;else sharedConfig.gather(id);
121
471
  }
122
472
  if (p) {
123
- const [s, set] = createSignal$1(undefined, {
124
- equals: false
473
+ _pendingBoundaries++;
474
+ onCleanup(() => {
475
+ if (!isDisposed(o)) return;
476
+ sharedConfig.cleanupFragment?.(id);
125
477
  });
126
- s();
478
+ const set = createBoundaryTrigger();
127
479
  if (p !== "$$f") {
128
- p.then(() => {
129
- sharedConfig.gather(id);
130
- sharedConfig.hydrating = true;
480
+ const waitFor = assetPromise ? Promise.all([p, assetPromise]) : p;
481
+ waitFor.then(() => resumeBoundaryHydration(o, id, set), err => {
482
+ _pendingBoundaries--;
483
+ checkHydrationComplete();
484
+ runWithOwner(o, () => {
485
+ throw err;
486
+ });
487
+ });
488
+ } else {
489
+ const afterAssets = () => {
490
+ _pendingBoundaries--;
131
491
  set();
132
- flush();
133
- sharedConfig.hydrating = false;
134
- }, err => runWithOwner(o, () => {
135
- throw err;
136
- }));
137
- } else queueMicrotask(set);
492
+ checkHydrationComplete();
493
+ };
494
+ if (assetPromise) assetPromise.then(() => queueMicrotask(afterAssets));else queueMicrotask(afterAssets);
495
+ }
138
496
  return props.fallback;
139
497
  }
140
498
  }
499
+ if (assetPromise) {
500
+ _pendingBoundaries++;
501
+ const set = createBoundaryTrigger();
502
+ assetPromise.then(() => resumeBoundaryHydration(o, id, set));
503
+ return undefined;
504
+ }
141
505
  return createLoadBoundary(() => props.children, () => props.fallback);
142
506
  });
143
507
  }
@@ -145,11 +509,24 @@ function Loading(props) {
145
509
  function createComponent(Comp, props) {
146
510
  return untrack(() => Comp(props || {}));
147
511
  }
148
- function lazy(fn) {
512
+ function lazy(fn, moduleUrl) {
149
513
  let comp;
150
514
  let p;
151
515
  const wrap = props => {
152
- comp = createMemo$1(() => (p || (p = fn())).then(mod => mod.default));
516
+ if (sharedConfig.hydrating && moduleUrl) {
517
+ const cached = globalThis._$HY?.modules?.[moduleUrl];
518
+ if (!cached) {
519
+ throw new Error(`lazy() module "${moduleUrl}" was not preloaded before hydration. ` + "Ensure it is inside a Loading boundary.");
520
+ }
521
+ comp = () => cached.default;
522
+ }
523
+ if (!comp) {
524
+ p || (p = fn());
525
+ p.then(mod => {
526
+ comp = () => mod.default;
527
+ });
528
+ comp = createMemo$1(() => p.then(mod => mod.default));
529
+ }
153
530
  let Comp;
154
531
  return createMemo$1(() => (Comp = comp()) ? untrack(() => {
155
532
  return Comp(props);
@@ -191,10 +568,15 @@ function Show(props) {
191
568
  if (c) {
192
569
  const child = props.children;
193
570
  const fn = typeof child === "function" && child.length > 0;
194
- return fn ? untrack(() => child(() => {
195
- if (!untrack(condition)) throw narrowedError("Show");
196
- return conditionValue();
197
- })) : child;
571
+ return fn ? untrack(() => {
572
+ try {
573
+ return child(() => {
574
+ if (!untrack(condition)) throw narrowedError("Show");
575
+ return conditionValue();
576
+ });
577
+ } finally {
578
+ }
579
+ }) : child;
198
580
  }
199
581
  return props.fallback;
200
582
  }, undefined, undefined);
@@ -222,10 +604,15 @@ function Switch(props) {
222
604
  const [index, conditionValue, mp] = sel;
223
605
  const child = mp.children;
224
606
  const fn = typeof child === "function" && child.length > 0;
225
- return fn ? untrack(() => child(() => {
226
- if (untrack(switchFunc)()?.[0] !== index) throw narrowedError("Match");
227
- return conditionValue();
228
- })) : child;
607
+ return fn ? untrack(() => {
608
+ try {
609
+ return child(() => {
610
+ if (untrack(switchFunc)()?.[0] !== index) throw narrowedError("Match");
611
+ return conditionValue();
612
+ });
613
+ } finally {
614
+ }
615
+ }) : child;
229
616
  }, undefined, undefined);
230
617
  }
231
618
  function Match(props) {
@@ -242,4 +629,4 @@ function ssrHandleError() {}
242
629
  function ssrRunInScope() {}
243
630
  const DEV = undefined;
244
631
 
245
- export { $DEVCOMP, DEV, Errored, For, Loading, Match, Repeat, Show, Switch, children, createComponent, createContext, createMemo, createSignal, createUniqueId, enableHydration, lazy, sharedConfig, ssrHandleError, ssrRunInScope, useContext };
632
+ export { $DEVCOMP, DEV, Errored, For, Loading, Match, Repeat, Show, Switch, children, createComponent, createContext, createMemo, createOptimistic, createOptimisticStore, createProjection, createSignal, createStore, createUniqueId, enableHydration, lazy, sharedConfig, ssrHandleError, ssrRunInScope, useContext };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "solid-js",
3
3
  "description": "A declarative JavaScript library for building user interfaces.",
4
- "version": "2.0.0-experimental.14",
4
+ "version": "2.0.0-experimental.15",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -79,7 +79,7 @@
79
79
  "performance"
80
80
  ],
81
81
  "dependencies": {
82
- "@solidjs/signals": "^0.10.2",
82
+ "@solidjs/signals": "^0.10.8",
83
83
  "csstype": "^3.1.0",
84
84
  "seroval": "~1.5.0",
85
85
  "seroval-plugins": "~1.5.0"
@@ -66,7 +66,7 @@ export type Ref<T> = T | ((val: T) => void);
66
66
  export declare function createComponent<T extends Record<string, any>>(Comp: Component<T>, props: T): JSX.Element;
67
67
  export declare function lazy<T extends Component<any>>(fn: () => Promise<{
68
68
  default: T;
69
- }>): T & {
69
+ }>, moduleUrl?: string): T & {
70
70
  preload: () => Promise<{
71
71
  default: T;
72
72
  }>;
@@ -1,6 +1,18 @@
1
- import { createMemo as coreMemo, createSignal as coreSignal } from "@solidjs/signals";
1
+ import { createErrorBoundary as coreErrorBoundary, createMemo as coreMemo, createSignal as coreSignal, createOptimistic as coreOptimistic, type ProjectionOptions, type Store, type StoreSetter } from "@solidjs/signals";
2
2
  import { JSX } from "../jsx.js";
3
- export { createStore, createProjection, createOptimistic, createOptimisticStore } from "@solidjs/signals";
3
+ declare module "@solidjs/signals" {
4
+ interface MemoOptions<T> {
5
+ deferStream?: boolean;
6
+ ssrSource?: "server" | "hybrid" | "initial" | "client";
7
+ }
8
+ interface SignalOptions<T> {
9
+ deferStream?: boolean;
10
+ ssrSource?: "server" | "hybrid" | "initial" | "client";
11
+ }
12
+ }
13
+ export type HydrationProjectionOptions = ProjectionOptions & {
14
+ ssrSource?: "server" | "hybrid" | "initial" | "client";
15
+ };
4
16
  export type HydrationContext = {};
5
17
  type SharedConfig = {
6
18
  hydrating: boolean;
@@ -10,14 +22,33 @@ type SharedConfig = {
10
22
  load?: (id: string) => Promise<any> | any;
11
23
  has?: (id: string) => boolean;
12
24
  gather?: (key: string) => void;
25
+ cleanupFragment?: (id: string) => void;
13
26
  registry?: Map<string, Element>;
14
27
  done: boolean;
15
28
  getNextContextId(): string;
16
29
  };
17
30
  export declare const sharedConfig: SharedConfig;
31
+ /**
32
+ * Registers a callback to run once when all hydration completes
33
+ * (all boundaries hydrated or cancelled). If hydration is already
34
+ * complete (or not hydrating), fires via queueMicrotask.
35
+ */
36
+ export declare function onHydrationEnd(callback: () => void): void;
18
37
  export declare function enableHydration(): void;
19
38
  export declare const createMemo: typeof coreMemo;
20
39
  export declare const createSignal: typeof coreSignal;
40
+ export declare const createErrorBoundary: typeof coreErrorBoundary;
41
+ export declare const createOptimistic: typeof coreOptimistic;
42
+ export declare const createProjection: <T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue?: T, options?: HydrationProjectionOptions) => Store<T>;
43
+ type NoFn<T> = T extends Function ? never : T;
44
+ export declare const createStore: {
45
+ <T extends object = {}>(store: NoFn<T> | Store<NoFn<T>>): [get: Store<T>, set: StoreSetter<T>];
46
+ <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store?: NoFn<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions): [get: Store<T>, set: StoreSetter<T>];
47
+ };
48
+ export declare const createOptimisticStore: {
49
+ <T extends object = {}>(store: NoFn<T> | Store<NoFn<T>>): [get: Store<T>, set: StoreSetter<T>];
50
+ <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store?: NoFn<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions): [get: Store<T>, set: StoreSetter<T>];
51
+ };
21
52
  /**
22
53
  * Tracks all resources inside a component and renders a fallback until they are all resolved
23
54
  * ```typescript
@@ -33,3 +64,4 @@ export declare function Loading(props: {
33
64
  fallback?: JSX.Element;
34
65
  children: JSX.Element;
35
66
  }): JSX.Element;
67
+ export {};
@@ -50,11 +50,15 @@ export type Ref<T> = T | ((val: T) => void);
50
50
  export declare function createComponent<T extends Record<string, any>>(Comp: Component<T>, props: T): JSX.Element;
51
51
  /**
52
52
  * Lazy load a function component asynchronously.
53
- * On server, caches the promise and throws NotReadyError if not yet loaded.
53
+ * On server, returns a createMemo that throws NotReadyError until the module resolves,
54
+ * allowing resolveSSRNode to capture it as a fine-grained hole. The memo naturally
55
+ * scopes the owner so hydration IDs align with the client's createMemo in lazy().
56
+ * Requires `moduleUrl` for SSR — the bundler plugin injects the module specifier
57
+ * so the server can look up client chunk URLs from the asset manifest.
54
58
  */
55
59
  export declare function lazy<T extends Component<any>>(fn: () => Promise<{
56
60
  default: T;
57
- }>): T & {
61
+ }>, moduleUrl?: string): T & {
58
62
  preload: () => Promise<{
59
63
  default: T;
60
64
  }>;
@@ -1,5 +1,5 @@
1
- export { $PROXY, $TRACK, action, createEffect, createMemo, createOptimistic, createOptimisticStore, createProjection, createReaction, createRenderEffect, createRoot, createSignal, createStore, createTrackedEffect, deep, flatten, flush, getObserver, getOwner, isEqual, isRefreshing, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, pending, reconcile, refresh, repeat, resolve, NotReadyError, runWithOwner, snapshot, untrack } from "./signals.js";
2
- export type { Accessor, ComputeFunction, EffectFunction, EffectOptions, Merge, NoInfer, NotWrappable, Omit, Owner, Signal, SignalOptions, Setter, Store, SolidStore, StoreNode, StoreSetter } from "./signals.js";
1
+ export { $PROXY, $TRACK, action, createEffect, createMemo, createOptimistic, createOptimisticStore, createProjection, createReaction, createRenderEffect, createRoot, createSignal, createStore, createTrackedEffect, deep, flatten, flush, getObserver, getOwner, isEqual, isRefreshing, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, pending, reconcile, refresh, repeat, resolve, NotReadyError, runWithOwner, snapshot, createDeepProxy, untrack } from "./signals.js";
2
+ export type { Accessor, ComputeFunction, EffectFunction, EffectOptions, Merge, NoInfer, NotWrappable, Omit, Owner, Signal, SignalOptions, Setter, Store, SolidStore, StoreNode, StoreSetter, PatchOp } from "./signals.js";
3
3
  export { $DEVCOMP, children, createContext, useContext, ssrRunInScope } from "./core.js";
4
4
  export type { ChildrenReturn, Context, ContextProviderComponent, ResolvedChildren, ResolvedJSXElement } from "./core.js";
5
5
  export * from "./component.js";
@@ -6,13 +6,34 @@ type SSRTemplateObject = {
6
6
  export type HydrationContext = {
7
7
  id: string;
8
8
  count: number;
9
- serialize: (id: string, v: Promise<any> | any, deferStream?: boolean) => void;
9
+ /**
10
+ * Serialize a value for client hydration.
11
+ * In renderToStream (async: true), accepts promises and async iterables.
12
+ * In renderToString (async: false), only synchronous values are allowed —
13
+ * passing async values will throw.
14
+ */
15
+ serialize: (id: string, v: any, deferStream?: boolean) => void;
10
16
  resolve(value: any): SSRTemplateObject;
11
17
  ssr(template: string[], ...values: any[]): SSRTemplateObject;
12
18
  escape(value: any): string;
13
19
  replace: (id: string, replacement: () => any) => void;
14
20
  block: (p: Promise<any>) => void;
15
21
  registerFragment: (v: string) => (v?: string, err?: any) => boolean;
22
+ /** Register a client-side asset URL discovered during SSR (e.g. from lazy()). */
23
+ registerAsset?: (type: "module" | "style", url: string) => void;
24
+ /** Register a moduleUrl-to-entryUrl mapping for the current boundary. */
25
+ registerModule?: (moduleUrl: string, entryUrl: string) => void;
26
+ /** Resolve a module's JS and CSS assets from the asset manifest. Set by dom-expressions. */
27
+ resolveAssets?: (moduleUrl: string) => {
28
+ js: string[];
29
+ css: string[];
30
+ } | null;
31
+ /** Retrieve the moduleUrl-to-entryUrl map for a boundary. */
32
+ getBoundaryModules?: (id: string) => Record<string, string> | null;
33
+ /** @internal Tracks which Loading boundary is currently rendering. Set by dom-expressions via applyAssetTracking(). */
34
+ _currentBoundaryId?: string | null;
35
+ assets: any[];
36
+ /** True only in renderToStream — enables async data serialization and streaming. */
16
37
  async?: boolean;
17
38
  noHydrate: boolean;
18
39
  };