@solidjs/signals 2.0.0-rc.2 → 2.0.0-rc.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.js +120 -24
- package/dist/node.cjs +190 -99
- package/dist/prod/core/optimistic.js +37 -15
- package/dist/prod/core/scheduler.js +8 -8
- package/dist/prod/core/verdict.js +7 -0
- package/dist/prod/store/next/optimistic.js +3 -3
- package/dist/prod/store/next/projection.js +107 -45
- package/dist/types/core/invariants.d.ts +1 -1
- package/dist/types-cjs/core/invariants.d.cts +1 -1
- package/package.json +15 -15
- package/dist/types/store/optimistic.d.ts +0 -45
- package/dist/types/store/projection.d.ts +0 -70
- package/dist/types/store/reconcile.d.ts +0 -46
- package/dist/types-cjs/store/optimistic.d.cts +0 -45
- package/dist/types-cjs/store/projection.d.cts +0 -70
- package/dist/types-cjs/store/reconcile.d.cts +0 -46
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { type Refreshable } from "../core/index.cjs";
|
|
2
|
-
import { type NoFn, type ProjectionOptions, type Store, type StoreSetter } from "./store.cjs";
|
|
3
|
-
/**
|
|
4
|
-
* The store equivalent of `createOptimistic`. Writes inside an `action`
|
|
5
|
-
* transition are tentative — they show up immediately but auto-revert (or
|
|
6
|
-
* reconcile to the action's resolved value) once the transition finishes.
|
|
7
|
-
*
|
|
8
|
-
* Use this for optimistic UI on collection-shaped data. For single-value
|
|
9
|
-
* optimistic state, prefer `createOptimistic`.
|
|
10
|
-
*
|
|
11
|
-
* - Plain form: `createOptimisticStore(initialValue)`.
|
|
12
|
-
* - Derived form: `createOptimisticStore(fn, seed, options?)` — a projection
|
|
13
|
-
* store whose authoritative value is recomputed by `fn` and whose
|
|
14
|
-
* optimistic overlay reverts after each transition.
|
|
15
|
-
*
|
|
16
|
-
* `options.key` defaults to `"id"`; specify it only when your data uses a
|
|
17
|
-
* different identity field (e.g. `{ key: "uuid" }` or `{ key: t => t.slug }`),
|
|
18
|
-
* or `null` to merge positionally. Restating the default just adds noise.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```ts
|
|
22
|
-
* const [todos, setTodos] = createOptimisticStore<Todo[]>([]);
|
|
23
|
-
*
|
|
24
|
-
* // Mutation: optimistic add, then in-place reconcile to the saved row.
|
|
25
|
-
* const addTodo = action(function* (text: string) {
|
|
26
|
-
* const tempId = crypto.randomUUID();
|
|
27
|
-
* setTodos(t => { t.push({ id: tempId, text, pending: true }); });
|
|
28
|
-
* const saved = yield api.createTodo(text);
|
|
29
|
-
* setTodos(t => {
|
|
30
|
-
* const i = t.findIndex(x => x.id === tempId);
|
|
31
|
-
* if (i >= 0) t[i] = saved;
|
|
32
|
-
* });
|
|
33
|
-
* });
|
|
34
|
-
*
|
|
35
|
-
* // Return form: filter is the natural shape for removal.
|
|
36
|
-
* const removeTodo = action(function* (id: string) {
|
|
37
|
-
* setTodos(t => t.filter(x => x.id !== id));
|
|
38
|
-
* yield api.removeTodo(id);
|
|
39
|
-
* });
|
|
40
|
-
* ```
|
|
41
|
-
*
|
|
42
|
-
* @returns `[store: Store<T>, setStore: StoreSetter<T>]`
|
|
43
|
-
*/
|
|
44
|
-
export declare function createOptimisticStore<T extends object = {}>(store: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Store<T>, set: StoreSetter<T>];
|
|
45
|
-
export declare function createOptimisticStore<T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { type Computed, type Refreshable } from "../core/index.cjs";
|
|
2
|
-
import { type NoFn, type ProjectionOptions, type Store } from "./store.cjs";
|
|
3
|
-
export declare function createProjectionInternal<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T>, options?: ProjectionOptions): {
|
|
4
|
-
store: Refreshable<Store<T>>;
|
|
5
|
-
node: Computed<void | T>;
|
|
6
|
-
};
|
|
7
|
-
/**
|
|
8
|
-
* Creates a derived (projected) store. Like `createMemo` but for stores: the
|
|
9
|
-
* derive function receives a mutable draft and either mutates it in place
|
|
10
|
-
* (canonical) or returns a new value. Either way the result is reconciled
|
|
11
|
-
* against the previous draft by `options.key` (default `"id"`), so surviving
|
|
12
|
-
* items keep their proxy identity — only added/removed items are
|
|
13
|
-
* created/disposed.
|
|
14
|
-
*
|
|
15
|
-
* If the derive returns a different entity than the one currently held (the
|
|
16
|
-
* `/users/1` → `/users/2` shape), the store swaps to it rather than merging,
|
|
17
|
-
* and nothing below it is treated as surviving.
|
|
18
|
-
*
|
|
19
|
-
* Returns the projected store directly (no setter — reads only).
|
|
20
|
-
*
|
|
21
|
-
* Use this when you want the structural-sharing / per-property tracking
|
|
22
|
-
* behaviour of a store on top of a derived computation. For simple read-only
|
|
23
|
-
* derivations, `createMemo` is lighter.
|
|
24
|
-
*
|
|
25
|
-
* @param fn receives the current draft; mutate it in place or return new
|
|
26
|
-
* data. Return is convenient for filter/derive shapes where mutation is
|
|
27
|
-
* awkward.
|
|
28
|
-
* @param seed the backing store value to wrap and reconcile into
|
|
29
|
-
* @param options `ProjectionOptions` — `name`, `key`. `key` defaults to
|
|
30
|
-
* `"id"`; specify it only when your data uses a different identity field
|
|
31
|
-
* (e.g. `{ key: "uuid" }` or `{ key: u => u.slug }`), or `null` to merge
|
|
32
|
-
* positionally with no keyed pass.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```ts
|
|
36
|
-
* // Mutation form — update individual fields on the draft.
|
|
37
|
-
* const summary = createProjection<{ total: number; active: number }>(
|
|
38
|
-
* draft => {
|
|
39
|
-
* draft.total = users().length;
|
|
40
|
-
* draft.active = users().filter(u => u.active).length;
|
|
41
|
-
* },
|
|
42
|
-
* { total: 0, active: 0 }
|
|
43
|
-
* );
|
|
44
|
-
*
|
|
45
|
-
* // Return form — produce a derived collection. Reconciled by `id` so each
|
|
46
|
-
* // surviving user keeps the same store identity across recomputes.
|
|
47
|
-
* const activeUsers = createProjection<User[]>(
|
|
48
|
-
* () => allUsers().filter(u => u.active),
|
|
49
|
-
* []
|
|
50
|
-
* );
|
|
51
|
-
* ```
|
|
52
|
-
*
|
|
53
|
-
* @see {@link https://github.com/solidjs/x-reactivity#createprojection}
|
|
54
|
-
*/
|
|
55
|
-
export declare function createProjection<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): Refreshable<Store<T>>;
|
|
56
|
-
/**
|
|
57
|
-
* Shared projection computed body used by both `createProjection` and the derived
|
|
58
|
-
* form of `createOptimisticStore`. Encapsulates the write-trap draft, `storeSetter`
|
|
59
|
-
* wrapping, the `handleAsync` subscription with a setter callback, and the commit
|
|
60
|
-
* path (which must always go through `storeSetter` so the `writeOnly` guard is
|
|
61
|
-
* engaged during `reconcile`'s property reads).
|
|
62
|
-
*
|
|
63
|
-
* `wrapCommit` is invoked for every commit (sync return and each async yield) and
|
|
64
|
-
* lets callers layer extra context around the write — e.g. the optimistic store
|
|
65
|
-
* re-enters `setProjectionWriteActive` so reconciles target `STORE_OVERRIDE`
|
|
66
|
-
* instead of `STORE_OPTIMISTIC_OVERRIDE` even when an async yield fires outside
|
|
67
|
-
* the outer `setProjectionWriteActive` scope.
|
|
68
|
-
*/
|
|
69
|
-
export declare function runProjectionComputed<T extends object>(wrappedStore: Store<T>, fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, key: string | ((item: NonNullable<any>) => any) | null, wrapCommit?: (write: () => void) => void, onDraftWrite?: () => void): Computed<void | T>;
|
|
70
|
-
export declare function createWriteTraps(isActive?: () => boolean, onDraftWrite?: () => void): ProxyHandler<any>;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared body of `reconcile()` and the projection commit. `replace` is the
|
|
3
|
-
* only difference: a projection commit is a value swap, not a merge — its root
|
|
4
|
-
* proxy is a cell handed out by `createProjection` that can never change
|
|
5
|
-
* reference, so a derive returning a different entity is not the slot mistake
|
|
6
|
-
* `reconcile()` throws on. Nothing below the root survives that swap, which is
|
|
7
|
-
* the rule the keyed diff already applies at a nested slot on a key mismatch.
|
|
8
|
-
*
|
|
9
|
-
* @internal
|
|
10
|
-
*/
|
|
11
|
-
export declare function reconcileState(value: any, state: any, key: any, replace: boolean): void;
|
|
12
|
-
/**
|
|
13
|
-
* Returns a draft-mutating function that smart-merges `value` into a store,
|
|
14
|
-
* preserving fine-grained reactivity: only changed leaves trigger updates.
|
|
15
|
-
*
|
|
16
|
-
* With a `key` (default `"id"`), array items whose key matches between old
|
|
17
|
-
* and new states keep their identity (updated in place, moves and removals
|
|
18
|
-
* update the corresponding signals) — the shape for keyed server payloads.
|
|
19
|
-
* Items without the key field fall back to positional matching.
|
|
20
|
-
*
|
|
21
|
-
* With `key: null`, matching is purely positional: index N of the new array
|
|
22
|
-
* merges into index N of the old, and object properties merge recursively —
|
|
23
|
-
* the classic pattern for fixed-shape data that churns in place (dashboards,
|
|
24
|
-
* monitors), where no keyed diff pass is needed or wanted.
|
|
25
|
-
*
|
|
26
|
-
* Merging into a slot that holds a *different* entity throws — the caller
|
|
27
|
-
* picked the slot, so a key mismatch there is a bug.
|
|
28
|
-
*
|
|
29
|
-
* @param value the next state to merge in
|
|
30
|
-
* @param key property name (string) or extractor function for stable
|
|
31
|
-
* identity (default `"id"`); pass `null` for positional merging
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```ts
|
|
35
|
-
* const [todos, setTodos] = createStore<Todo[]>([]);
|
|
36
|
-
*
|
|
37
|
-
* async function refresh() {
|
|
38
|
-
* const fresh = await api.getTodos();
|
|
39
|
-
* setTodos(reconcile(fresh)); // diff-merge by `id`
|
|
40
|
-
* }
|
|
41
|
-
*
|
|
42
|
-
* // fixed-shape polling data — positional merge
|
|
43
|
-
* setStats(reconcile(nextStats, null));
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
export declare function reconcile<T extends U, U>(value: T, key?: string | ((item: NonNullable<any>) => any) | null): (state: U) => void;
|