solid-js 2.0.0-beta.7 → 2.0.0-beta.9
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/CHEATSHEET.md +562 -0
- package/README.md +44 -188
- package/dist/dev.cjs +21 -41
- package/dist/dev.js +21 -41
- package/dist/server.cjs +122 -37
- package/dist/server.js +122 -37
- package/dist/solid.cjs +21 -41
- package/dist/solid.js +21 -41
- package/package.json +7 -5
- package/types/client/component.d.ts +50 -0
- package/types/client/core.d.ts +98 -21
- package/types/client/flow.d.ts +97 -24
- package/types/client/hydration.d.ts +409 -22
- package/types/index.d.ts +1 -1
- package/types/jsx-properties.d.ts +2 -5
- package/types/jsx.d.ts +108 -77
- package/types/server/core.d.ts +14 -9
- package/types/server/flow.d.ts +40 -7
- package/types/server/hydration.d.ts +18 -1
- package/types/server/index.d.ts +1 -1
- package/types/server/signals.d.ts +30 -10
- package/types-cjs/client/component.d.cts +50 -0
- package/types-cjs/client/core.d.cts +98 -21
- package/types-cjs/client/flow.d.cts +97 -24
- package/types-cjs/client/hydration.d.cts +409 -22
- package/types-cjs/index.d.cts +1 -1
- package/types-cjs/jsx-properties.d.cts +2 -5
- package/types-cjs/jsx.d.cts +108 -77
- package/types-cjs/server/core.d.cts +14 -9
- package/types-cjs/server/flow.d.cts +40 -7
- package/types-cjs/server/hydration.d.cts +18 -1
- package/types-cjs/server/index.d.cts +1 -1
- package/types-cjs/server/signals.d.cts +30 -10
package/dist/solid.cjs
CHANGED
|
@@ -277,9 +277,12 @@ function hydrateSignalFromAsyncIterable(coreFn, compute, options) {
|
|
|
277
277
|
return it;
|
|
278
278
|
}
|
|
279
279
|
};
|
|
280
|
-
return coreFn(
|
|
280
|
+
return coreFn(prev => {
|
|
281
|
+
subFetch(compute, prev);
|
|
282
|
+
return iterable;
|
|
283
|
+
}, options);
|
|
281
284
|
}
|
|
282
|
-
function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
285
|
+
function hydrateStoreFromAsyncIterable(coreFn, fn, initialValue, options) {
|
|
283
286
|
const parent = signals.getOwner();
|
|
284
287
|
const expectedId = signals.peekNextChildId(parent);
|
|
285
288
|
if (!sharedConfig.has(expectedId)) return null;
|
|
@@ -289,6 +292,10 @@ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
|
289
292
|
let isFirst = true;
|
|
290
293
|
let buffered = null;
|
|
291
294
|
return coreFn(draft => {
|
|
295
|
+
const {
|
|
296
|
+
proxy
|
|
297
|
+
} = createShadowDraft(draft);
|
|
298
|
+
subFetch(fn, proxy);
|
|
292
299
|
const process = res => {
|
|
293
300
|
if (res.done) return {
|
|
294
301
|
done: true,
|
|
@@ -296,11 +303,16 @@ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
|
296
303
|
};
|
|
297
304
|
if (isFirst) {
|
|
298
305
|
isFirst = false;
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
306
|
+
signals.setSnapshotCapture(false);
|
|
307
|
+
try {
|
|
308
|
+
if (Array.isArray(res.value)) {
|
|
309
|
+
for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i];
|
|
310
|
+
draft.length = res.value.length;
|
|
311
|
+
} else {
|
|
312
|
+
Object.assign(draft, res.value);
|
|
313
|
+
}
|
|
314
|
+
} finally {
|
|
315
|
+
signals.setSnapshotCapture(true);
|
|
304
316
|
}
|
|
305
317
|
} else {
|
|
306
318
|
applyPatches(draft, res.value);
|
|
@@ -369,13 +381,6 @@ function hydratedCreateMemo(compute, options) {
|
|
|
369
381
|
setHydrated(true);
|
|
370
382
|
return memo;
|
|
371
383
|
}
|
|
372
|
-
if (ssrSource === "initial") {
|
|
373
|
-
return signals.createMemo(prev => {
|
|
374
|
-
if (!sharedConfig.hydrating) return compute(prev);
|
|
375
|
-
subFetch(compute, prev);
|
|
376
|
-
return prev;
|
|
377
|
-
}, options);
|
|
378
|
-
}
|
|
379
384
|
const aiResult = hydrateSignalFromAsyncIterable(signals.createMemo, compute, options);
|
|
380
385
|
if (aiResult !== null) return aiResult;
|
|
381
386
|
return signals.createMemo(prev => readSerializedOrCompute(compute, prev), options);
|
|
@@ -395,13 +400,6 @@ function hydratedCreateSignal(fn, second) {
|
|
|
395
400
|
setHydrated(true);
|
|
396
401
|
return sig;
|
|
397
402
|
}
|
|
398
|
-
if (ssrSource === "initial") {
|
|
399
|
-
return signals.createSignal(prev => {
|
|
400
|
-
if (!sharedConfig.hydrating) return fn(prev);
|
|
401
|
-
subFetch(fn, prev);
|
|
402
|
-
return prev;
|
|
403
|
-
}, second);
|
|
404
|
-
}
|
|
405
403
|
const aiResult = hydrateSignalFromAsyncIterable(signals.createSignal, fn, second);
|
|
406
404
|
if (aiResult !== null) return aiResult;
|
|
407
405
|
return signals.createSignal(prev => readSerializedOrCompute(fn, prev), second);
|
|
@@ -441,13 +439,6 @@ function hydratedCreateOptimistic(fn, second) {
|
|
|
441
439
|
setHydrated(true);
|
|
442
440
|
return sig;
|
|
443
441
|
}
|
|
444
|
-
if (ssrSource === "initial") {
|
|
445
|
-
return signals.createOptimistic(prev => {
|
|
446
|
-
if (!sharedConfig.hydrating) return fn(prev);
|
|
447
|
-
subFetch(fn, prev);
|
|
448
|
-
return prev;
|
|
449
|
-
}, second);
|
|
450
|
-
}
|
|
451
442
|
const aiResult = hydrateSignalFromAsyncIterable(signals.createOptimistic, fn, second);
|
|
452
443
|
if (aiResult !== null) return aiResult;
|
|
453
444
|
return signals.createOptimistic(prev => readSerializedOrCompute(fn, prev), second);
|
|
@@ -491,7 +482,7 @@ function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) {
|
|
|
491
482
|
setHydrated(true);
|
|
492
483
|
return result;
|
|
493
484
|
}
|
|
494
|
-
const aiResult = hydrateStoreFromAsyncIterable(coreFn, initialValue, options);
|
|
485
|
+
const aiResult = hydrateStoreFromAsyncIterable(coreFn, fn, initialValue, options);
|
|
495
486
|
if (aiResult !== null) return aiResult;
|
|
496
487
|
return coreFn(wrapStoreFn(fn), initialValue, options);
|
|
497
488
|
}
|
|
@@ -499,21 +490,18 @@ function hydratedCreateStore(first, second, third) {
|
|
|
499
490
|
if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createStore(first, second, third);
|
|
500
491
|
markTopLevelSnapshotScope();
|
|
501
492
|
const ssrSource = third?.ssrSource;
|
|
502
|
-
if (ssrSource === "initial") return signals.createStore(second ?? {});
|
|
503
493
|
return hydrateStoreLikeFn(signals.createStore, first, second ?? {}, third, ssrSource);
|
|
504
494
|
}
|
|
505
495
|
function hydratedCreateOptimisticStore(first, second, third) {
|
|
506
496
|
if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createOptimisticStore(first, second, third);
|
|
507
497
|
markTopLevelSnapshotScope();
|
|
508
498
|
const ssrSource = third?.ssrSource;
|
|
509
|
-
if (ssrSource === "initial") return signals.createOptimisticStore(second ?? {});
|
|
510
499
|
return hydrateStoreLikeFn(signals.createOptimisticStore, first, second ?? {}, third, ssrSource);
|
|
511
500
|
}
|
|
512
501
|
function hydratedCreateProjection(fn, initialValue, options) {
|
|
513
502
|
if (!sharedConfig.hydrating) return signals.createProjection(fn, initialValue, options);
|
|
514
503
|
markTopLevelSnapshotScope();
|
|
515
504
|
const ssrSource = options?.ssrSource;
|
|
516
|
-
if (ssrSource === "initial") return signals.createProjection(draft => draft, initialValue, options);
|
|
517
505
|
return hydrateStoreLikeFn(signals.createProjection, fn, initialValue, options, ssrSource);
|
|
518
506
|
}
|
|
519
507
|
function hydratedEffect(coreFn, compute, effectFn, options) {
|
|
@@ -535,14 +523,6 @@ function hydratedEffect(coreFn, compute, effectFn, options) {
|
|
|
535
523
|
setHydrated(true);
|
|
536
524
|
return;
|
|
537
525
|
}
|
|
538
|
-
if (ssrSource === "initial") {
|
|
539
|
-
coreFn(prev => {
|
|
540
|
-
if (!sharedConfig.hydrating) return compute(prev);
|
|
541
|
-
subFetch(compute, prev);
|
|
542
|
-
return prev;
|
|
543
|
-
}, effectFn, options);
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
526
|
markTopLevelSnapshotScope();
|
|
547
527
|
coreFn(prev => readSerializedOrCompute(compute, prev), effectFn, options);
|
|
548
528
|
}
|
|
@@ -854,7 +834,7 @@ function Loading(props) {
|
|
|
854
834
|
}
|
|
855
835
|
function Reveal(props) {
|
|
856
836
|
return signals.createRevealOrder(() => props.children, {
|
|
857
|
-
|
|
837
|
+
order: () => props.order ?? "sequential",
|
|
858
838
|
collapsed: () => !!props.collapsed
|
|
859
839
|
});
|
|
860
840
|
}
|
package/dist/solid.js
CHANGED
|
@@ -276,9 +276,12 @@ function hydrateSignalFromAsyncIterable(coreFn, compute, options) {
|
|
|
276
276
|
return it;
|
|
277
277
|
}
|
|
278
278
|
};
|
|
279
|
-
return coreFn(
|
|
279
|
+
return coreFn(prev => {
|
|
280
|
+
subFetch(compute, prev);
|
|
281
|
+
return iterable;
|
|
282
|
+
}, options);
|
|
280
283
|
}
|
|
281
|
-
function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
284
|
+
function hydrateStoreFromAsyncIterable(coreFn, fn, initialValue, options) {
|
|
282
285
|
const parent = getOwner();
|
|
283
286
|
const expectedId = peekNextChildId(parent);
|
|
284
287
|
if (!sharedConfig.has(expectedId)) return null;
|
|
@@ -288,6 +291,10 @@ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
|
288
291
|
let isFirst = true;
|
|
289
292
|
let buffered = null;
|
|
290
293
|
return coreFn(draft => {
|
|
294
|
+
const {
|
|
295
|
+
proxy
|
|
296
|
+
} = createShadowDraft(draft);
|
|
297
|
+
subFetch(fn, proxy);
|
|
291
298
|
const process = res => {
|
|
292
299
|
if (res.done) return {
|
|
293
300
|
done: true,
|
|
@@ -295,11 +302,16 @@ function hydrateStoreFromAsyncIterable(coreFn, initialValue, options) {
|
|
|
295
302
|
};
|
|
296
303
|
if (isFirst) {
|
|
297
304
|
isFirst = false;
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
305
|
+
setSnapshotCapture(false);
|
|
306
|
+
try {
|
|
307
|
+
if (Array.isArray(res.value)) {
|
|
308
|
+
for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i];
|
|
309
|
+
draft.length = res.value.length;
|
|
310
|
+
} else {
|
|
311
|
+
Object.assign(draft, res.value);
|
|
312
|
+
}
|
|
313
|
+
} finally {
|
|
314
|
+
setSnapshotCapture(true);
|
|
303
315
|
}
|
|
304
316
|
} else {
|
|
305
317
|
applyPatches(draft, res.value);
|
|
@@ -368,13 +380,6 @@ function hydratedCreateMemo(compute, options) {
|
|
|
368
380
|
setHydrated(true);
|
|
369
381
|
return memo;
|
|
370
382
|
}
|
|
371
|
-
if (ssrSource === "initial") {
|
|
372
|
-
return createMemo$1(prev => {
|
|
373
|
-
if (!sharedConfig.hydrating) return compute(prev);
|
|
374
|
-
subFetch(compute, prev);
|
|
375
|
-
return prev;
|
|
376
|
-
}, options);
|
|
377
|
-
}
|
|
378
383
|
const aiResult = hydrateSignalFromAsyncIterable(createMemo$1, compute, options);
|
|
379
384
|
if (aiResult !== null) return aiResult;
|
|
380
385
|
return createMemo$1(prev => readSerializedOrCompute(compute, prev), options);
|
|
@@ -394,13 +399,6 @@ function hydratedCreateSignal(fn, second) {
|
|
|
394
399
|
setHydrated(true);
|
|
395
400
|
return sig;
|
|
396
401
|
}
|
|
397
|
-
if (ssrSource === "initial") {
|
|
398
|
-
return createSignal$1(prev => {
|
|
399
|
-
if (!sharedConfig.hydrating) return fn(prev);
|
|
400
|
-
subFetch(fn, prev);
|
|
401
|
-
return prev;
|
|
402
|
-
}, second);
|
|
403
|
-
}
|
|
404
402
|
const aiResult = hydrateSignalFromAsyncIterable(createSignal$1, fn, second);
|
|
405
403
|
if (aiResult !== null) return aiResult;
|
|
406
404
|
return createSignal$1(prev => readSerializedOrCompute(fn, prev), second);
|
|
@@ -440,13 +438,6 @@ function hydratedCreateOptimistic(fn, second) {
|
|
|
440
438
|
setHydrated(true);
|
|
441
439
|
return sig;
|
|
442
440
|
}
|
|
443
|
-
if (ssrSource === "initial") {
|
|
444
|
-
return createOptimistic$1(prev => {
|
|
445
|
-
if (!sharedConfig.hydrating) return fn(prev);
|
|
446
|
-
subFetch(fn, prev);
|
|
447
|
-
return prev;
|
|
448
|
-
}, second);
|
|
449
|
-
}
|
|
450
441
|
const aiResult = hydrateSignalFromAsyncIterable(createOptimistic$1, fn, second);
|
|
451
442
|
if (aiResult !== null) return aiResult;
|
|
452
443
|
return createOptimistic$1(prev => readSerializedOrCompute(fn, prev), second);
|
|
@@ -490,7 +481,7 @@ function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) {
|
|
|
490
481
|
setHydrated(true);
|
|
491
482
|
return result;
|
|
492
483
|
}
|
|
493
|
-
const aiResult = hydrateStoreFromAsyncIterable(coreFn, initialValue, options);
|
|
484
|
+
const aiResult = hydrateStoreFromAsyncIterable(coreFn, fn, initialValue, options);
|
|
494
485
|
if (aiResult !== null) return aiResult;
|
|
495
486
|
return coreFn(wrapStoreFn(fn), initialValue, options);
|
|
496
487
|
}
|
|
@@ -498,21 +489,18 @@ function hydratedCreateStore(first, second, third) {
|
|
|
498
489
|
if (typeof first !== "function" || !sharedConfig.hydrating) return createStore$1(first, second, third);
|
|
499
490
|
markTopLevelSnapshotScope();
|
|
500
491
|
const ssrSource = third?.ssrSource;
|
|
501
|
-
if (ssrSource === "initial") return createStore$1(second ?? {});
|
|
502
492
|
return hydrateStoreLikeFn(createStore$1, first, second ?? {}, third, ssrSource);
|
|
503
493
|
}
|
|
504
494
|
function hydratedCreateOptimisticStore(first, second, third) {
|
|
505
495
|
if (typeof first !== "function" || !sharedConfig.hydrating) return createOptimisticStore$1(first, second, third);
|
|
506
496
|
markTopLevelSnapshotScope();
|
|
507
497
|
const ssrSource = third?.ssrSource;
|
|
508
|
-
if (ssrSource === "initial") return createOptimisticStore$1(second ?? {});
|
|
509
498
|
return hydrateStoreLikeFn(createOptimisticStore$1, first, second ?? {}, third, ssrSource);
|
|
510
499
|
}
|
|
511
500
|
function hydratedCreateProjection(fn, initialValue, options) {
|
|
512
501
|
if (!sharedConfig.hydrating) return createProjection$1(fn, initialValue, options);
|
|
513
502
|
markTopLevelSnapshotScope();
|
|
514
503
|
const ssrSource = options?.ssrSource;
|
|
515
|
-
if (ssrSource === "initial") return createProjection$1(draft => draft, initialValue, options);
|
|
516
504
|
return hydrateStoreLikeFn(createProjection$1, fn, initialValue, options, ssrSource);
|
|
517
505
|
}
|
|
518
506
|
function hydratedEffect(coreFn, compute, effectFn, options) {
|
|
@@ -534,14 +522,6 @@ function hydratedEffect(coreFn, compute, effectFn, options) {
|
|
|
534
522
|
setHydrated(true);
|
|
535
523
|
return;
|
|
536
524
|
}
|
|
537
|
-
if (ssrSource === "initial") {
|
|
538
|
-
coreFn(prev => {
|
|
539
|
-
if (!sharedConfig.hydrating) return compute(prev);
|
|
540
|
-
subFetch(compute, prev);
|
|
541
|
-
return prev;
|
|
542
|
-
}, effectFn, options);
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
525
|
markTopLevelSnapshotScope();
|
|
546
526
|
coreFn(prev => readSerializedOrCompute(compute, prev), effectFn, options);
|
|
547
527
|
}
|
|
@@ -853,7 +833,7 @@ function Loading(props) {
|
|
|
853
833
|
}
|
|
854
834
|
function Reveal(props) {
|
|
855
835
|
return createRevealOrder(() => props.children, {
|
|
856
|
-
|
|
836
|
+
order: () => props.order ?? "sequential",
|
|
857
837
|
collapsed: () => !!props.collapsed
|
|
858
838
|
});
|
|
859
839
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solid-js",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"description": "Reactive JavaScript library for building user interfaces. Compiles JSX to real DOM with fine-grained signal-based updates — no virtual DOM.",
|
|
4
|
+
"version": "2.0.0-beta.9",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://solidjs.com",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/solidjs/solid"
|
|
10
|
+
"url": "git+https://github.com/solidjs/solid.git",
|
|
11
|
+
"directory": "packages/solid"
|
|
11
12
|
},
|
|
12
13
|
"main": "./dist/server.cjs",
|
|
13
14
|
"module": "./dist/server.js",
|
|
@@ -20,7 +21,8 @@
|
|
|
20
21
|
"types",
|
|
21
22
|
"types-cjs",
|
|
22
23
|
"jsx-runtime.d.ts",
|
|
23
|
-
"package.json"
|
|
24
|
+
"package.json",
|
|
25
|
+
"CHEATSHEET.md"
|
|
24
26
|
],
|
|
25
27
|
"exports": {
|
|
26
28
|
".": {
|
|
@@ -126,7 +128,7 @@
|
|
|
126
128
|
"performance"
|
|
127
129
|
],
|
|
128
130
|
"dependencies": {
|
|
129
|
-
"@solidjs/signals": "^2.0.0-beta.
|
|
131
|
+
"@solidjs/signals": "^2.0.0-beta.9",
|
|
130
132
|
"csstype": "^3.1.0",
|
|
131
133
|
"seroval": "~1.5.0",
|
|
132
134
|
"seroval-plugins": "~1.5.0"
|
|
@@ -63,7 +63,39 @@ export type ComponentProps<T extends ValidComponent> = T extends Component<infer
|
|
|
63
63
|
* @example Component<{ref: Ref<Element>}>
|
|
64
64
|
*/
|
|
65
65
|
export type Ref<T> = T | ((val: T) => void);
|
|
66
|
+
/**
|
|
67
|
+
* Invokes a component, wrapping the call in `untrack` so that reactive reads
|
|
68
|
+
* inside the component body don't subscribe the parent computation. Compiled
|
|
69
|
+
* JSX uses this internally; manual calls are rarely needed unless authoring a
|
|
70
|
+
* custom JSX factory or renderer.
|
|
71
|
+
*/
|
|
66
72
|
export declare function createComponent<T extends Record<string, any>>(Comp: Component<T>, props: T): JSX.Element;
|
|
73
|
+
/**
|
|
74
|
+
* Defines a code-split component. The returned component triggers its dynamic
|
|
75
|
+
* import on first render and suspends through any enclosing `<Loading>`
|
|
76
|
+
* boundary while the chunk is in flight. Call `.preload()` to start the
|
|
77
|
+
* import early (e.g. on hover).
|
|
78
|
+
*
|
|
79
|
+
* @param fn dynamic import returning the module's default export
|
|
80
|
+
* @param moduleUrl optional module URL used during hydration to look up
|
|
81
|
+
* preloaded chunks; usually injected by the bundler integration
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```tsx
|
|
85
|
+
* const Profile = lazy(() => import("./Profile"));
|
|
86
|
+
*
|
|
87
|
+
* function App() {
|
|
88
|
+
* return (
|
|
89
|
+
* <Loading fallback={<Spinner />}>
|
|
90
|
+
* <Profile id="42" />
|
|
91
|
+
* </Loading>
|
|
92
|
+
* );
|
|
93
|
+
* }
|
|
94
|
+
*
|
|
95
|
+
* // Preload before the user clicks
|
|
96
|
+
* <button onMouseEnter={() => Profile.preload()}>Open profile</button>
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
67
99
|
export declare function lazy<T extends Component<any>>(fn: () => Promise<{
|
|
68
100
|
default: T;
|
|
69
101
|
}>, moduleUrl?: string): T & {
|
|
@@ -72,4 +104,22 @@ export declare function lazy<T extends Component<any>>(fn: () => Promise<{
|
|
|
72
104
|
}>;
|
|
73
105
|
moduleUrl?: string;
|
|
74
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* Returns a stable id string that matches between server-rendered and
|
|
109
|
+
* client-hydrated trees. Use it for `<label for>`, `aria-labelledby`, and
|
|
110
|
+
* other attributes that need consistent ids across SSR.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```tsx
|
|
114
|
+
* function Field(props: { label: string }) {
|
|
115
|
+
* const id = createUniqueId();
|
|
116
|
+
* return (
|
|
117
|
+
* <>
|
|
118
|
+
* <label for={id}>{props.label}</label>
|
|
119
|
+
* <input id={id} />
|
|
120
|
+
* </>
|
|
121
|
+
* );
|
|
122
|
+
* }
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
75
125
|
export declare function createUniqueId(): string;
|
package/types/client/core.d.ts
CHANGED
|
@@ -9,34 +9,101 @@ export type ContextProviderComponent<T> = FlowComponent<{
|
|
|
9
9
|
}>;
|
|
10
10
|
export interface Context<T> extends ContextProviderComponent<T> {
|
|
11
11
|
id: symbol;
|
|
12
|
-
defaultValue: T;
|
|
12
|
+
defaultValue: T | undefined;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Creates a Context
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
15
|
+
* Creates a Context for sharing state with descendants of a Provider in the
|
|
16
|
+
* component tree.
|
|
17
|
+
*
|
|
18
|
+
* The returned `Context` is itself a provider component — pass it a `value`
|
|
19
|
+
* prop to scope a value to its children. Read it inside descendants with
|
|
20
|
+
* `useContext`.
|
|
21
|
+
*
|
|
22
|
+
* Two forms:
|
|
23
|
+
*
|
|
24
|
+
* - **`createContext<T>()`** (default-less, the canonical form). Reading via
|
|
25
|
+
* `useContext` outside an enclosing Provider throws `ContextNotFoundError`.
|
|
26
|
+
* Use this for everything that carries reactive state — signals, stores,
|
|
27
|
+
* `[state, actions]` tuples, services. The Provider is mandatory by
|
|
28
|
+
* construction; the throw makes a missing Provider a loud bug instead of a
|
|
29
|
+
* silent no-op. The annotation `<T>` is required because there is no value
|
|
30
|
+
* to infer from.
|
|
31
|
+
* - **`createContext<T>(defaultValue)`** (default form). Reserved for the
|
|
32
|
+
* narrow case of contexts whose value is a primitive with a meaningful
|
|
33
|
+
* static fallback (theme, locale, frozen config). Outside any Provider,
|
|
34
|
+
* `useContext` returns `defaultValue`.
|
|
35
|
+
*
|
|
36
|
+
* If you want truly app-wide state, **don't use Context** — a module-scope
|
|
37
|
+
* signal/store *is* a global. Context is for scoping state to a subtree;
|
|
38
|
+
* that's why a Provider is required.
|
|
39
|
+
*
|
|
40
|
+
* @param defaultValue optional default; only meaningful for primitive
|
|
41
|
+
* fallbacks. Omit for any context carrying reactive state.
|
|
42
|
+
* @param options `{ name }` for debugging in development
|
|
43
|
+
* @returns a context object that doubles as its own provider component
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```tsx
|
|
47
|
+
* // Reactive payload — default-less, throws if no Provider.
|
|
48
|
+
* type TodosCtx = readonly [Store<Todo[]>, TodoActions];
|
|
49
|
+
* const TodosContext = createContext<TodosCtx>();
|
|
50
|
+
*
|
|
51
|
+
* function App() {
|
|
52
|
+
* return (
|
|
53
|
+
* <TodosContext value={createTodos()}>
|
|
54
|
+
* <TodoList />
|
|
55
|
+
* </TodosContext>
|
|
56
|
+
* );
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* function TodoList() {
|
|
60
|
+
* const [todos, { addTodo }] = useContext(TodosContext); // typed as TodosCtx
|
|
61
|
+
* // ...
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* // Primitive default — falls back to "light" outside a Provider.
|
|
68
|
+
* const ThemeContext = createContext<"light" | "dark">("light");
|
|
69
|
+
*
|
|
70
|
+
* function Button() {
|
|
71
|
+
* const theme = useContext(ThemeContext); // "light" | "dark"
|
|
72
|
+
* return <button class={theme}>Click</button>;
|
|
21
73
|
* }
|
|
22
|
-
* export function createContext<T>(
|
|
23
|
-
* defaultValue?: T,
|
|
24
|
-
* options?: { name?: string }
|
|
25
|
-
* ): Context<T | undefined>;
|
|
26
74
|
* ```
|
|
27
|
-
* @param defaultValue optional default to inject into context
|
|
28
|
-
* @param options allows to set a name in dev mode for debugging purposes
|
|
29
|
-
* @returns The context that contains the Provider Component and that can be used with `useContext`
|
|
30
75
|
*
|
|
31
76
|
* @description https://docs.solidjs.com/reference/component-apis/create-context
|
|
32
77
|
*/
|
|
33
|
-
export declare function createContext<T>(defaultValue?:
|
|
34
|
-
export declare function createContext<T>(defaultValue: T, options?: EffectOptions): Context<T>;
|
|
78
|
+
export declare function createContext<T>(defaultValue?: T, options?: EffectOptions): Context<T>;
|
|
35
79
|
/**
|
|
36
|
-
*
|
|
80
|
+
* Reads the current value of a context.
|
|
81
|
+
*
|
|
82
|
+
* - For `createContext<T>()` (default-less): returns the value from the
|
|
83
|
+
* nearest enclosing Provider, or throws `ContextNotFoundError` if none is
|
|
84
|
+
* mounted. Return type is `T` (no narrowing required).
|
|
85
|
+
* - For `createContext<T>(defaultValue)`: returns the value from the nearest
|
|
86
|
+
* enclosing Provider, or `defaultValue` if none is mounted.
|
|
37
87
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
88
|
+
* In Solid, `useContext` is the canonical way to read context. There is no
|
|
89
|
+
* need for a wrapper hook that throws on missing Provider — the default-less
|
|
90
|
+
* form already does that, and its return type is `T`.
|
|
91
|
+
*
|
|
92
|
+
* @param context a context returned from `createContext`
|
|
93
|
+
* @returns the value provided by the nearest enclosing Provider, or the
|
|
94
|
+
* default if one was supplied to `createContext`
|
|
95
|
+
* @throws `ContextNotFoundError` if no Provider is mounted and the context
|
|
96
|
+
* was created without a default
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```tsx
|
|
100
|
+
* const TodosContext = createContext<TodosCtx>();
|
|
101
|
+
*
|
|
102
|
+
* function TodoList() {
|
|
103
|
+
* const [todos, { addTodo }] = useContext(TodosContext); // throws if no Provider
|
|
104
|
+
* // ...
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
40
107
|
*
|
|
41
108
|
* @description https://docs.solidjs.com/reference/component-apis/use-context
|
|
42
109
|
*/
|
|
@@ -47,10 +114,20 @@ export type ChildrenReturn = Accessor<ResolvedChildren> & {
|
|
|
47
114
|
toArray: () => ResolvedJSXElement[];
|
|
48
115
|
};
|
|
49
116
|
/**
|
|
50
|
-
* Resolves
|
|
117
|
+
* Resolves a `children` accessor and exposes the result as an accessor with
|
|
118
|
+
* a `.toArray()` helper. Use this when a component needs to inspect or
|
|
119
|
+
* iterate over its children rather than just render them through.
|
|
51
120
|
*
|
|
52
121
|
* @param fn an accessor for the children
|
|
53
|
-
* @returns
|
|
122
|
+
* @returns an accessor of the resolved children, with `.toArray()` for iteration
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```tsx
|
|
126
|
+
* function List(props: { children: JSX.Element }) {
|
|
127
|
+
* const items = children(() => props.children);
|
|
128
|
+
* return <ul>{items.toArray().map(item => <li>{item}</li>)}</ul>;
|
|
129
|
+
* }
|
|
130
|
+
* ```
|
|
54
131
|
*
|
|
55
132
|
* @description https://docs.solidjs.com/reference/component-apis/children
|
|
56
133
|
*/
|