solid-js 2.0.0-beta.1 → 2.0.0-beta.3

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/dev.cjs CHANGED
@@ -38,17 +38,10 @@ function devComponent(Comp, props) {
38
38
  owner._props = props;
39
39
  owner._name = Comp.name;
40
40
  owner._component = Comp;
41
- return signals.untrack(() => {
42
- Object.assign(Comp, {
43
- [$DEVCOMP]: true
44
- });
45
- signals.setStrictRead(`<${Comp.name || "Anonymous"}>`);
46
- try {
47
- return Comp(props);
48
- } finally {
49
- signals.setStrictRead(false);
50
- }
41
+ Object.assign(Comp, {
42
+ [$DEVCOMP]: true
51
43
  });
44
+ return signals.untrack(() => Comp(props), `<${Comp.name || "Anonymous"}>`);
52
45
  }, {
53
46
  transparent: true
54
47
  });
@@ -161,11 +154,41 @@ function subFetch(fn, prev) {
161
154
  Promise = ogPromise;
162
155
  }
163
156
  }
164
- function consumeFirstSync(ai) {
165
- const iter = ai[Symbol.asyncIterator]();
166
- const r = iter.next();
167
- const value = !(r instanceof Promise) && !r.done ? r.value : undefined;
168
- return [value, iter];
157
+ function syncThenable(value) {
158
+ return {
159
+ then(fn) {
160
+ fn(value);
161
+ }
162
+ };
163
+ }
164
+ function normalizeIterator(it) {
165
+ let first = true;
166
+ let buffered = null;
167
+ return {
168
+ next() {
169
+ if (first) {
170
+ first = false;
171
+ const r = it.next();
172
+ return r && typeof r.then === "function" ? r : syncThenable(r);
173
+ }
174
+ if (buffered) {
175
+ const b = buffered;
176
+ buffered = null;
177
+ return b;
178
+ }
179
+ let latest = it.next();
180
+ if (latest && typeof latest.then === "function") return latest;
181
+ while (!latest.done) {
182
+ const peek = it.next();
183
+ if (peek && typeof peek.then === "function") {
184
+ buffered = peek;
185
+ break;
186
+ }
187
+ latest = peek;
188
+ }
189
+ return Promise.resolve(latest);
190
+ }
191
+ };
169
192
  }
170
193
  function applyPatches(target, patches) {
171
194
  for (const patch of patches) {
@@ -182,63 +205,163 @@ function applyPatches(target, patches) {
182
205
  }
183
206
  }
184
207
  }
185
- function scheduleIteratorConsumption(iter, apply) {
186
- const consume = () => {
187
- while (true) {
188
- const n = iter.next();
189
- if (n instanceof Promise) {
190
- n.then(r => {
191
- if (r.done) return;
192
- apply(r.value);
193
- consume();
194
- });
195
- return;
208
+ function isAsyncIterable(v) {
209
+ return v != null && typeof v[Symbol.asyncIterator] === "function";
210
+ }
211
+ function createShadowDraft(realDraft) {
212
+ const shadow = JSON.parse(JSON.stringify(realDraft));
213
+ let useShadow = true;
214
+ return {
215
+ proxy: new Proxy(shadow, {
216
+ get(_, prop) {
217
+ return useShadow ? shadow[prop] : realDraft[prop];
218
+ },
219
+ set(_, prop, value) {
220
+ if (useShadow) {
221
+ shadow[prop] = value;
222
+ return true;
223
+ }
224
+ return Reflect.set(realDraft, prop, value);
225
+ },
226
+ deleteProperty(_, prop) {
227
+ if (useShadow) {
228
+ delete shadow[prop];
229
+ return true;
230
+ }
231
+ return Reflect.deleteProperty(realDraft, prop);
232
+ },
233
+ has(_, prop) {
234
+ return prop in (useShadow ? shadow : realDraft);
235
+ },
236
+ ownKeys() {
237
+ return Reflect.ownKeys(useShadow ? shadow : realDraft);
238
+ },
239
+ getOwnPropertyDescriptor(_, prop) {
240
+ return Object.getOwnPropertyDescriptor(useShadow ? shadow : realDraft, prop);
196
241
  }
197
- if (n.done) break;
198
- apply(n.value);
242
+ }),
243
+ activate() {
244
+ useShadow = false;
199
245
  }
200
246
  };
201
- consume();
202
247
  }
203
- function isAsyncIterable(v) {
204
- return v != null && typeof v[Symbol.asyncIterator] === "function";
248
+ function wrapFirstYield(iterable, activate) {
249
+ const srcIt = iterable[Symbol.asyncIterator]();
250
+ let first = true;
251
+ return {
252
+ [Symbol.asyncIterator]() {
253
+ return {
254
+ next() {
255
+ const p = srcIt.next();
256
+ if (first) {
257
+ first = false;
258
+ return p.then(r => {
259
+ activate();
260
+ return r.done ? r : {
261
+ done: false,
262
+ value: undefined
263
+ };
264
+ });
265
+ }
266
+ return p;
267
+ }
268
+ };
269
+ }
270
+ };
205
271
  }
206
272
  function hydrateSignalFromAsyncIterable(coreFn, compute, value, options) {
207
273
  const parent = signals.getOwner();
208
274
  const expectedId = signals.peekNextChildId(parent);
209
275
  if (!sharedConfig.has(expectedId)) return null;
210
- const initP = sharedConfig.load(expectedId);
211
- if (!isAsyncIterable(initP)) return null;
212
- const [firstValue, iter] = consumeFirstSync(initP);
213
- const [get, set] = signals.createSignal(firstValue);
214
- const result = coreFn(() => get(), firstValue, options);
215
- scheduleIteratorConsumption(iter, v => {
216
- set(() => v);
217
- signals.flush();
218
- });
219
- return result;
276
+ const loaded = sharedConfig.load(expectedId);
277
+ if (!isAsyncIterable(loaded)) return null;
278
+ const it = normalizeIterator(loaded[Symbol.asyncIterator]());
279
+ const iterable = {
280
+ [Symbol.asyncIterator]() {
281
+ return it;
282
+ }
283
+ };
284
+ return coreFn(() => iterable, value, options);
220
285
  }
221
286
  function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
222
287
  const parent = signals.getOwner();
223
288
  const expectedId = signals.peekNextChildId(parent);
224
289
  if (!sharedConfig.has(expectedId)) return null;
225
- const initP = sharedConfig.load(expectedId);
226
- if (!isAsyncIterable(initP)) return null;
227
- const [firstState, iter] = consumeFirstSync(initP);
228
- const [store, setStore] = coreFn(() => {}, firstState ?? initialValue, options);
229
- scheduleIteratorConsumption(iter, patches => {
230
- setStore(d => {
231
- applyPatches(d, patches);
232
- });
233
- });
234
- return [store, setStore];
290
+ const loaded = sharedConfig.load(expectedId);
291
+ if (!isAsyncIterable(loaded)) return null;
292
+ const srcIt = loaded[Symbol.asyncIterator]();
293
+ let isFirst = true;
294
+ let buffered = null;
295
+ return coreFn(draft => {
296
+ const process = res => {
297
+ if (res.done) return {
298
+ done: true,
299
+ value: undefined
300
+ };
301
+ if (isFirst) {
302
+ isFirst = false;
303
+ if (Array.isArray(res.value)) {
304
+ for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i];
305
+ draft.length = res.value.length;
306
+ } else {
307
+ Object.assign(draft, res.value);
308
+ }
309
+ } else {
310
+ applyPatches(draft, res.value);
311
+ }
312
+ return {
313
+ done: false,
314
+ value: undefined
315
+ };
316
+ };
317
+ return {
318
+ [Symbol.asyncIterator]() {
319
+ return {
320
+ next() {
321
+ if (isFirst) {
322
+ const r = srcIt.next();
323
+ return r && typeof r.then === "function" ? {
324
+ then(fn, rej) {
325
+ r.then(v => fn(process(v)), rej);
326
+ }
327
+ } : syncThenable(process(r));
328
+ }
329
+ if (buffered) {
330
+ const b = buffered;
331
+ buffered = null;
332
+ return b.then(process);
333
+ }
334
+ let r = srcIt.next();
335
+ if (r && typeof r.then === "function") {
336
+ return r.then(process);
337
+ }
338
+ let result = process(r);
339
+ while (!r.done) {
340
+ const peek = srcIt.next();
341
+ if (peek && typeof peek.then === "function") {
342
+ buffered = peek;
343
+ break;
344
+ }
345
+ r = peek;
346
+ if (!r.done) result = process(r);
347
+ }
348
+ return Promise.resolve(result);
349
+ }
350
+ };
351
+ }
352
+ };
353
+ }, initialValue, options);
235
354
  }
236
355
  function hydratedCreateMemo(compute, value, options) {
237
- if (!sharedConfig.hydrating) return signals.createMemo(compute, value, options);
356
+ if (!sharedConfig.hydrating || options?.transparent) {
357
+ return signals.createMemo(compute, value, options);
358
+ }
238
359
  markTopLevelSnapshotScope();
239
360
  const ssrSource = options?.ssrSource;
240
361
  if (ssrSource === "client") {
241
- const [hydrated, setHydrated] = signals.createSignal(false);
362
+ const [hydrated, setHydrated] = signals.createSignal(false, {
363
+ pureWrite: true
364
+ });
242
365
  const memo = signals.createMemo(prev => {
243
366
  if (!hydrated()) return prev ?? value;
244
367
  return compute(prev);
@@ -269,7 +392,9 @@ function hydratedCreateSignal(fn, second, third) {
269
392
  markTopLevelSnapshotScope();
270
393
  const ssrSource = third?.ssrSource;
271
394
  if (ssrSource === "client") {
272
- const [hydrated, setHydrated] = signals.createSignal(false);
395
+ const [hydrated, setHydrated] = signals.createSignal(false, {
396
+ pureWrite: true
397
+ });
273
398
  const sig = signals.createSignal(prev => {
274
399
  if (!hydrated()) return prev ?? second;
275
400
  return fn(prev);
@@ -320,7 +445,9 @@ function hydratedCreateOptimistic(fn, second, third) {
320
445
  markTopLevelSnapshotScope();
321
446
  const ssrSource = third?.ssrSource;
322
447
  if (ssrSource === "client") {
323
- const [hydrated, setHydrated] = signals.createSignal(false);
448
+ const [hydrated, setHydrated] = signals.createSignal(false, {
449
+ pureWrite: true
450
+ });
324
451
  const sig = signals.createOptimistic(prev => {
325
452
  if (!hydrated()) return prev ?? second;
326
453
  return fn(prev);
@@ -346,14 +473,7 @@ function hydratedCreateOptimistic(fn, second, third) {
346
473
  return init != null ? (subFetch(fn, prev), init) : fn(prev);
347
474
  }, second, third);
348
475
  }
349
- function wrapStoreFn(fn, ssrSource) {
350
- if (ssrSource === "initial") {
351
- return draft => {
352
- if (!sharedConfig.hydrating) return fn(draft);
353
- subFetch(fn, draft);
354
- return undefined;
355
- };
356
- }
476
+ function wrapStoreFn(fn) {
357
477
  return draft => {
358
478
  const o = signals.getOwner();
359
479
  if (!sharedConfig.hydrating) return fn(draft);
@@ -363,44 +483,77 @@ function wrapStoreFn(fn, ssrSource) {
363
483
  return init != null ? (subFetch(fn, draft), init) : fn(draft);
364
484
  };
365
485
  }
486
+ function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) {
487
+ if (ssrSource === "client") {
488
+ const [hydrated, setHydrated] = signals.createSignal(false, {
489
+ pureWrite: true
490
+ });
491
+ const result = coreFn(draft => {
492
+ if (!hydrated()) return;
493
+ return fn(draft);
494
+ }, initialValue, options);
495
+ setHydrated(true);
496
+ return result;
497
+ }
498
+ if (ssrSource === "hybrid") {
499
+ const [hydrated, setHydrated] = signals.createSignal(false, {
500
+ pureWrite: true
501
+ });
502
+ const result = coreFn(draft => {
503
+ const o = signals.getOwner();
504
+ if (!hydrated()) {
505
+ if (sharedConfig.has(o.id)) {
506
+ const initP = sharedConfig.load(o.id);
507
+ const init = initP?.v ?? initP;
508
+ if (init != null) {
509
+ subFetch(fn, draft);
510
+ return init;
511
+ }
512
+ }
513
+ return fn(draft);
514
+ }
515
+ const {
516
+ proxy,
517
+ activate
518
+ } = createShadowDraft(draft);
519
+ const r = fn(proxy);
520
+ return isAsyncIterable(r) ? wrapFirstYield(r, activate) : r;
521
+ }, initialValue, options);
522
+ setHydrated(true);
523
+ return result;
524
+ }
525
+ const aiResult = hydrateStoreFromAsyncIterable(coreFn, initialValue, options);
526
+ if (aiResult !== null) return aiResult;
527
+ return coreFn(wrapStoreFn(fn), initialValue, options);
528
+ }
366
529
  function hydratedCreateStore(first, second, third) {
367
530
  if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createStore(first, second, third);
368
531
  markTopLevelSnapshotScope();
369
532
  const ssrSource = third?.ssrSource;
370
- if (ssrSource === "client" || ssrSource === "initial") {
371
- return signals.createStore(second ?? {}, undefined, third);
372
- }
373
- const aiResult = hydrateStoreFromAsyncIterable(signals.createStore, second ?? {}, third);
374
- if (aiResult !== null) return aiResult;
375
- return signals.createStore(wrapStoreFn(first, ssrSource), second, third);
533
+ if (ssrSource === "initial") return signals.createStore(second ?? {}, undefined, third);
534
+ return hydrateStoreLikeFn(signals.createStore, first, second ?? {}, third, ssrSource);
376
535
  }
377
536
  function hydratedCreateOptimisticStore(first, second, third) {
378
537
  if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createOptimisticStore(first, second, third);
379
538
  markTopLevelSnapshotScope();
380
539
  const ssrSource = third?.ssrSource;
381
- if (ssrSource === "client" || ssrSource === "initial") {
382
- return signals.createOptimisticStore(second ?? {}, undefined, third);
383
- }
384
- const aiResult = hydrateStoreFromAsyncIterable(signals.createOptimisticStore, second ?? {}, third);
385
- if (aiResult !== null) return aiResult;
386
- return signals.createOptimisticStore(wrapStoreFn(first, ssrSource), second, third);
540
+ if (ssrSource === "initial") return signals.createOptimisticStore(second ?? {}, undefined, third);
541
+ return hydrateStoreLikeFn(signals.createOptimisticStore, first, second ?? {}, third, ssrSource);
387
542
  }
388
543
  function hydratedCreateProjection(fn, initialValue, options) {
389
544
  if (!sharedConfig.hydrating) return signals.createProjection(fn, initialValue, options);
390
545
  markTopLevelSnapshotScope();
391
546
  const ssrSource = options?.ssrSource;
392
- if (ssrSource === "client" || ssrSource === "initial") {
393
- return signals.createProjection(draft => draft, initialValue, options);
394
- }
395
- const aiResult = hydrateStoreFromAsyncIterable(signals.createStore, initialValue, options);
396
- if (aiResult !== null) return aiResult[0];
397
- return signals.createProjection(wrapStoreFn(fn, ssrSource), initialValue, options);
547
+ if (ssrSource === "initial") return signals.createProjection(draft => draft, initialValue, options);
548
+ return hydrateStoreLikeFn(signals.createProjection, fn, initialValue, options, ssrSource);
398
549
  }
399
550
  function hydratedEffect(coreFn, compute, effectFn, value, options) {
400
551
  if (!sharedConfig.hydrating) return coreFn(compute, effectFn, value, options);
401
552
  const ssrSource = options?.ssrSource;
402
553
  if (ssrSource === "client") {
403
- const [hydrated, setHydrated] = signals.createSignal(false);
554
+ const [hydrated, setHydrated] = signals.createSignal(false, {
555
+ pureWrite: true
556
+ });
404
557
  let active = false;
405
558
  coreFn(prev => {
406
559
  if (!hydrated()) return value;
@@ -534,13 +687,16 @@ function resumeBoundaryHydration(o, id, set) {
534
687
  set();
535
688
  signals.flush();
536
689
  _snapshotRootOwner = null;
537
- _hydratingValue = false;
538
690
  signals.releaseSnapshotScope(o);
539
691
  signals.flush();
692
+ _hydratingValue = false;
540
693
  checkHydrationComplete();
541
694
  }
542
695
  function Loading(props) {
543
- if (!sharedConfig.hydrating) return signals.createLoadBoundary(() => props.children, () => props.fallback);
696
+ const onOpt = props.on ? {
697
+ on: () => props.on()
698
+ } : undefined;
699
+ if (!sharedConfig.hydrating) return signals.createLoadingBoundary(() => props.children, () => props.fallback, onOpt);
544
700
  return signals.createMemo(() => {
545
701
  const o = signals.getOwner();
546
702
  const id = o.id;
@@ -588,7 +744,8 @@ function Loading(props) {
588
744
  assetPromise.then(() => resumeBoundaryHydration(o, id, set));
589
745
  return undefined;
590
746
  }
591
- return signals.createLoadBoundary(() => props.children, () => props.fallback);
747
+ const boundary = signals.createLoadingBoundary(() => props.children, () => props.fallback, onOpt);
748
+ return boundary;
592
749
  });
593
750
  }
594
751
  function NoHydration(props) {
@@ -674,17 +831,10 @@ function Show(props) {
674
831
  if (c) {
675
832
  const child = props.children;
676
833
  const fn = typeof child === "function" && child.length > 0;
677
- return fn ? signals.untrack(() => {
678
- signals.setStrictRead("<Show>");
679
- try {
680
- return child(() => {
681
- if (!signals.untrack(condition)) throw narrowedError("Show");
682
- return conditionValue();
683
- });
684
- } finally {
685
- signals.setStrictRead(false);
686
- }
687
- }) : child;
834
+ return fn ? signals.untrack(() => child(() => {
835
+ if (!signals.untrack(condition)) throw narrowedError("Show");
836
+ return conditionValue();
837
+ }), "<Show>") : child;
688
838
  }
689
839
  return props.fallback;
690
840
  }, undefined, {
@@ -717,17 +867,10 @@ function Switch(props) {
717
867
  const [index, conditionValue, mp] = sel;
718
868
  const child = mp.children;
719
869
  const fn = typeof child === "function" && child.length > 0;
720
- return fn ? signals.untrack(() => {
721
- signals.setStrictRead("<Match>");
722
- try {
723
- return child(() => {
724
- if (signals.untrack(switchFunc)()?.[0] !== index) throw narrowedError("Match");
725
- return conditionValue();
726
- });
727
- } finally {
728
- signals.setStrictRead(false);
729
- }
730
- }) : child;
870
+ return fn ? signals.untrack(() => child(() => {
871
+ if (signals.untrack(switchFunc)()?.[0] !== index) throw narrowedError("Match");
872
+ return conditionValue();
873
+ }), "<Match>") : child;
731
874
  }, undefined, {
732
875
  name: "eval conditions"
733
876
  } );
@@ -758,6 +901,10 @@ Object.defineProperty(exports, "$PROXY", {
758
901
  enumerable: true,
759
902
  get: function () { return signals.$PROXY; }
760
903
  });
904
+ Object.defineProperty(exports, "$REFRESH", {
905
+ enumerable: true,
906
+ get: function () { return signals.$REFRESH; }
907
+ });
761
908
  Object.defineProperty(exports, "$TRACK", {
762
909
  enumerable: true,
763
910
  get: function () { return signals.$TRACK; }
@@ -770,6 +917,14 @@ Object.defineProperty(exports, "action", {
770
917
  enumerable: true,
771
918
  get: function () { return signals.action; }
772
919
  });
920
+ Object.defineProperty(exports, "createErrorBoundary", {
921
+ enumerable: true,
922
+ get: function () { return signals.createErrorBoundary; }
923
+ });
924
+ Object.defineProperty(exports, "createLoadingBoundary", {
925
+ enumerable: true,
926
+ get: function () { return signals.createLoadingBoundary; }
927
+ });
773
928
  Object.defineProperty(exports, "createOwner", {
774
929
  enumerable: true,
775
930
  get: function () { return signals.createOwner; }
@@ -790,6 +945,14 @@ Object.defineProperty(exports, "deep", {
790
945
  enumerable: true,
791
946
  get: function () { return signals.deep; }
792
947
  });
948
+ Object.defineProperty(exports, "enableExternalSource", {
949
+ enumerable: true,
950
+ get: function () { return signals.enableExternalSource; }
951
+ });
952
+ Object.defineProperty(exports, "enforceLoadingBoundary", {
953
+ enumerable: true,
954
+ get: function () { return signals.enforceLoadingBoundary; }
955
+ });
793
956
  Object.defineProperty(exports, "flatten", {
794
957
  enumerable: true,
795
958
  get: function () { return signals.flatten; }