solid-ctrl-flow 1.0.32 → 1.0.33
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/index.d.ts +59 -49
- package/dist/index.mjs +141 -126
- package/dist/index.umd.js +140 -125
- package/package.json +1 -1
- package/readMe.md +13 -12
package/dist/index.d.ts
CHANGED
|
@@ -64,10 +64,10 @@ export declare function bindTwoWay<S, D>(source: Signal<S>, dest: Signal<D>, to:
|
|
|
64
64
|
* <>
|
|
65
65
|
* ```
|
|
66
66
|
*/
|
|
67
|
-
export declare
|
|
67
|
+
export declare const Case: (props: {
|
|
68
68
|
value: any;
|
|
69
69
|
children: JSX.Element;
|
|
70
|
-
})
|
|
70
|
+
}) => JSX.Element;
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* Returns a {@link Signal} that applies the `??=` operator to the input one.
|
|
@@ -118,44 +118,25 @@ export declare function createExtractor(name?: string): {
|
|
|
118
118
|
readonly extracting: () => number | null;
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
/**
|
|
122
|
-
* Creates a context with a reactive value.
|
|
123
|
-
* Returns a provider with additional fields:
|
|
124
|
-
* - The `read` getter, which returns an {@link Accessor} to the value
|
|
125
|
-
* - The `runWith()` method, which executes {@link runWithContext} on the option
|
|
126
|
-
* @param init Initial value for the context
|
|
127
|
-
* @param def Default value to set when calling the provider without one
|
|
128
|
-
* @param name Name to give to the context
|
|
129
|
-
*/
|
|
130
|
-
export declare function createOption<T>(init: T, def?: T, name?: string): {
|
|
131
|
-
(props: {
|
|
132
|
-
value?: T;
|
|
133
|
-
children: JSX.Element;
|
|
134
|
-
}): JSX.Element;
|
|
135
|
-
/** Executes {@link runWithContext} on the provided option */
|
|
136
|
-
runWith<V extends T, R>(x: V, f: (x: V) => R): R;
|
|
137
|
-
} & {
|
|
138
|
-
/** Returns the {@link Accessor} for the value in the current context */
|
|
139
|
-
read: Accessor<T>;
|
|
140
|
-
};
|
|
141
|
-
|
|
142
121
|
/**
|
|
143
122
|
* Creates a {@link Resource} from the function {@link f}.
|
|
144
|
-
* The resource will be refetched each time one of the dependencies of {@link f} changes
|
|
123
|
+
* The resource will be refetched each time one of the dependencies of {@link f} changes.
|
|
124
|
+
* The only dependant signals that will be tracked are the ones before the first `await`
|
|
145
125
|
* @param f A reactive resource fetcher
|
|
146
126
|
*/
|
|
147
127
|
export declare function createReactiveResource<R>(f: EffectFunction<R | undefined, R>): Resource<Awaited<R>>;
|
|
148
128
|
|
|
149
|
-
/** Creates a scope for the value of {@link Debug.
|
|
150
|
-
export declare
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
129
|
+
/** Creates a scope for the value of {@link Debug.isDebug}, which allows you to display different things in debug mode */
|
|
130
|
+
export declare function Debug(props: {
|
|
131
|
+
value?: boolean;
|
|
132
|
+
children?: JSX.Element;
|
|
133
|
+
}): JSX.Element;
|
|
134
|
+
|
|
135
|
+
/** Internals of {@link Debug} */
|
|
136
|
+
export declare namespace Debug {
|
|
137
|
+
/** Returns an {@link Accessor} that tells whether the current {@link Owner} is in debug mode */
|
|
138
|
+
const isDebug: Accessor<boolean>;
|
|
139
|
+
}
|
|
159
140
|
|
|
160
141
|
/** Informations about a {@link Source} component */
|
|
161
142
|
declare type Info = {
|
|
@@ -172,12 +153,46 @@ declare type Info = {
|
|
|
172
153
|
*/
|
|
173
154
|
export declare function memoProps<T, K extends readonly (keyof T)[] = (keyof T)[]>(obj: T, keys?: K): Pick<T, K[number]>;
|
|
174
155
|
|
|
175
|
-
/**
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
156
|
+
/**
|
|
157
|
+
* Reactive {@link Context} with some additional built-in functionalities.
|
|
158
|
+
* The call signature returns the value in the current {@link Owner} (It's like calling {@link read})
|
|
159
|
+
*/
|
|
160
|
+
export declare abstract class ReactiveContext<T> extends ReactiveContext_base<T> {
|
|
161
|
+
/** The actual {@link Context} that contains the reactive {@link Accessor} to the value */
|
|
162
|
+
abstract ctx: Context<Accessor<T>>;
|
|
163
|
+
/**
|
|
164
|
+
* Returns the {@link Accessor} for the value in the current {@link Owner}.
|
|
165
|
+
* It's like calling {@link useContext}
|
|
166
|
+
*/
|
|
167
|
+
get read(): Accessor<T>;
|
|
168
|
+
/**
|
|
169
|
+
* Component that sets the value of the current {@link Context} for its children.
|
|
170
|
+
* If no value is provided then it will use the default value for {@link ctx}.
|
|
171
|
+
* The function is binded for the way solid compiles components inside other objects.
|
|
172
|
+
* (The value is memoized)
|
|
173
|
+
*/
|
|
174
|
+
get Provider(): (props: {
|
|
175
|
+
value?: T;
|
|
176
|
+
children: JSX.Element;
|
|
177
|
+
}) => JSX.Element;
|
|
178
|
+
/**
|
|
179
|
+
* Executes {@link runWithContext} on the current context
|
|
180
|
+
* @param value The value for the context
|
|
181
|
+
* @param f The function to run
|
|
182
|
+
* @returns The same thing {@link f} returned
|
|
183
|
+
*/
|
|
184
|
+
runWith<V extends T, R>(value: V, f: (x: V) => R): R;
|
|
185
|
+
runWith<R>(value: T | undefined, f: (x: T) => R): R;
|
|
186
|
+
/**
|
|
187
|
+
* Creates a {@link ReactiveContext}
|
|
188
|
+
* @param defaultValue Initial value for the context
|
|
189
|
+
* @param name Name to give to the context
|
|
190
|
+
*/
|
|
191
|
+
static create<T>(defaultValue?: undefined, name?: string): ReactiveContext<T | undefined>;
|
|
192
|
+
static create<T>(defaultValue: T, name?: string): ReactiveContext<T>;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
declare const ReactiveContext_base: new <T_1>() => Accessor<T_1>;
|
|
181
196
|
|
|
182
197
|
/**
|
|
183
198
|
* Executes a {@link Ref}.
|
|
@@ -188,13 +203,6 @@ export declare function OptionalSuspense(props: {
|
|
|
188
203
|
*/
|
|
189
204
|
export declare function refCall<T, U extends T = T>(ref: Ref<T> | undefined, value: U): U;
|
|
190
205
|
|
|
191
|
-
/**
|
|
192
|
-
* Executes {@link f} and then calls {@link d} regardless of errors.
|
|
193
|
-
* If {@link f} returns a {@link Promise}, {@link d} will be called asynchronously
|
|
194
|
-
* @returns The same thing {@link f} returned
|
|
195
|
-
*/
|
|
196
|
-
export declare function runAndDispose<R>(d: () => void, f: () => R): R;
|
|
197
|
-
|
|
198
206
|
/**
|
|
199
207
|
* Executes {@link f} with the provided value for the specified {@link Context}.
|
|
200
208
|
* You can pass `undefined` to {@link value} in order to get back the default value for {@link ctx}.
|
|
@@ -204,7 +212,9 @@ export declare function runAndDispose<R>(d: () => void, f: () => R): R;
|
|
|
204
212
|
* @param f The function to run
|
|
205
213
|
* @returns The same thing {@link f} returned
|
|
206
214
|
*/
|
|
207
|
-
export declare function runWithContext<T, R>(ctx: Context<T>, value:
|
|
215
|
+
export declare function runWithContext<T, V extends T, R>(ctx: Context<T>, value: V, f: (x: V) => R): R;
|
|
216
|
+
|
|
217
|
+
export declare function runWithContext<T, R>(ctx: Context<T>, value: T | undefined, f: (x: T) => R): R;
|
|
208
218
|
|
|
209
219
|
/**
|
|
210
220
|
* Executes {@link splitProps} and memoizes the first of the two returned objects
|
|
@@ -235,7 +245,7 @@ export declare function toSignal<T, K extends keyof T>(obj: Accessor<T>, k: Acce
|
|
|
235
245
|
* @param args Arguments for calling {@link f}
|
|
236
246
|
* @returns The same thing {@link f} returned
|
|
237
247
|
*/
|
|
238
|
-
export declare function untrackCall<F extends (...args: any[]) =>
|
|
248
|
+
export declare function untrackCall<F extends (...args: any[]) => unknown>(this: ThisParameterType<F>, f: F, ...args: Parameters<F>): ReturnType<F>;
|
|
239
249
|
|
|
240
250
|
/**
|
|
241
251
|
* Calls {@link f} maintaining its reactivity
|
package/dist/index.mjs
CHANGED
|
@@ -1,120 +1,88 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useContext, createMemo, createComponent, createContext, Match, mergeProps, onCleanup, For, Show, createRoot, createRenderEffect, on, untrack, splitProps, getOwner, createEffect, createResource } from "solid-js";
|
|
2
2
|
import { createMutable } from "solid-js/store";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return f(value);
|
|
3
|
+
class ReactiveContext extends Function {
|
|
4
|
+
/** The actual {@link Context} that contains the reactive {@link Accessor} to the value */
|
|
5
|
+
/**
|
|
6
|
+
* Returns the {@link Accessor} for the value in the current {@link Owner}.
|
|
7
|
+
* It's like calling {@link useContext}
|
|
8
|
+
*/
|
|
9
|
+
get read() {
|
|
10
|
+
return useContext(this.ctx);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Component that sets the value of the current {@link Context} for its children.
|
|
14
|
+
* If no value is provided then it will use the default value for {@link ctx}.
|
|
15
|
+
* The function is binded for the way solid compiles components inside other objects.
|
|
16
|
+
* (The value is memoized)
|
|
17
|
+
*/
|
|
18
|
+
get Provider() {
|
|
19
|
+
const {
|
|
20
|
+
ctx: ctx2
|
|
21
|
+
} = this;
|
|
22
|
+
return function(props) {
|
|
23
|
+
const memo = createMemo(() => props.value);
|
|
24
|
+
return createComponent(ctx2.Provider, {
|
|
25
|
+
value: memo,
|
|
26
|
+
get children() {
|
|
27
|
+
return props.children;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Executes {@link runWithContext} on the current context
|
|
34
|
+
* @param value The value for the context
|
|
35
|
+
* @param f The function to run
|
|
36
|
+
* @returns The same thing {@link f} returned
|
|
37
|
+
*/
|
|
38
|
+
runWith(value, f) {
|
|
39
|
+
return runWithContext(this.ctx, value === void 0 ? void 0 : () => value, (x) => f(x()));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates a {@link ReactiveContext}
|
|
43
|
+
* @param defaultValue Initial value for the context
|
|
44
|
+
* @param name Name to give to the context
|
|
45
|
+
*/
|
|
46
|
+
static create(defaultValue, name) {
|
|
47
|
+
const ctx2 = createContext(() => defaultValue, {
|
|
48
|
+
name
|
|
50
49
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const memo = createMemo(f);
|
|
56
|
-
createEffect(on(memo, () => refetch?.()));
|
|
57
|
-
const [get] = [, {
|
|
58
|
-
refetch
|
|
59
|
-
}] = createResource(memo);
|
|
60
|
-
return get;
|
|
61
|
-
}
|
|
62
|
-
function runAndDispose(d, f) {
|
|
63
|
-
try {
|
|
64
|
-
const out = f();
|
|
65
|
-
return out instanceof Promise ? out.finally(d) : (d(), out);
|
|
66
|
-
} catch (ex) {
|
|
67
|
-
throw d(), ex;
|
|
50
|
+
const f = () => out.read();
|
|
51
|
+
f.ctx = ctx2;
|
|
52
|
+
const out = Object.setPrototypeOf(f, ReactiveContext.prototype);
|
|
53
|
+
return out;
|
|
68
54
|
}
|
|
69
55
|
}
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
const d = createRoot((d2) => (createRenderEffect(on(get, (x) => set((prev) => to(x, prev)))), d2));
|
|
73
|
-
return onCleanup(d), d;
|
|
74
|
-
}
|
|
75
|
-
function bindTwoWay(source, dest, to = IDENTITY, from = IDENTITY) {
|
|
76
|
-
const a = bind(source, dest, to);
|
|
77
|
-
const b = bind(dest, source, from);
|
|
78
|
-
return () => (a(), b());
|
|
79
|
-
}
|
|
80
|
-
function toSetter(get, set) {
|
|
81
|
-
return (x) => {
|
|
82
|
-
const out = typeof x === "function" ? x(untrack(get)) : x;
|
|
83
|
-
return set(out), out;
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
function toSignal(obj, k) {
|
|
87
|
-
const get = () => obj()[k()];
|
|
88
|
-
return [get, toSetter(get, (v) => obj()[k()] = v)];
|
|
89
|
-
}
|
|
90
|
-
function coalesceSignal([get, set], f) {
|
|
91
|
-
return [() => get() ?? set(f), set];
|
|
92
|
-
}
|
|
93
|
-
function unwrapSignal(f) {
|
|
94
|
-
return [() => f()[0](), (x) => f()[1](x)];
|
|
95
|
-
}
|
|
96
|
-
const ctx = createContext(() => void 0, {
|
|
97
|
-
name: "case-when"
|
|
98
|
-
});
|
|
99
|
-
function Case(props) {
|
|
100
|
-
const memo = createMemo(() => props.value);
|
|
101
|
-
return createComponent(ctx.Provider, {
|
|
102
|
-
value: memo,
|
|
103
|
-
get children() {
|
|
104
|
-
return props.children;
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
56
|
+
const ctx$1 = ReactiveContext.create(void 0, "case-when");
|
|
57
|
+
const Case = ctx$1.Provider;
|
|
108
58
|
function When(props) {
|
|
109
59
|
const [mine, other] = splitAndMemoProps(props, ["value", "pred"]);
|
|
110
|
-
const
|
|
60
|
+
const {
|
|
61
|
+
read
|
|
62
|
+
} = ctx$1;
|
|
111
63
|
const pred = (x) => mine.pred ? mine.pred(x) : x === mine.value;
|
|
112
64
|
return createComponent(Match, mergeProps({
|
|
113
65
|
get when() {
|
|
114
|
-
return pred(
|
|
66
|
+
return pred(read());
|
|
115
67
|
}
|
|
116
68
|
}, other));
|
|
117
69
|
}
|
|
70
|
+
const ctx = ReactiveContext.create(false, "debug-scope");
|
|
71
|
+
function Debug(props) {
|
|
72
|
+
return createComponent(ctx.Provider, {
|
|
73
|
+
get value() {
|
|
74
|
+
return props.value ?? true;
|
|
75
|
+
},
|
|
76
|
+
get children() {
|
|
77
|
+
return props.children;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
(function(_Debug) {
|
|
82
|
+
Object.defineProperty(Debug, "isDebug", {
|
|
83
|
+
get: () => ctx.read
|
|
84
|
+
});
|
|
85
|
+
})(Debug || (Debug = {}));
|
|
118
86
|
function createExtractor(name = "extractor") {
|
|
119
87
|
const ctx2 = createContext(void 0, {
|
|
120
88
|
name
|
|
@@ -188,41 +156,88 @@ function Joint(props) {
|
|
|
188
156
|
}
|
|
189
157
|
});
|
|
190
158
|
}
|
|
191
|
-
const
|
|
192
|
-
function
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
159
|
+
const IDENTITY = (x) => x;
|
|
160
|
+
function bind([get], [, set], to = IDENTITY) {
|
|
161
|
+
const d = createRoot((d2) => (createRenderEffect(on(get, (x) => set((prev) => to(x, prev)))), d2));
|
|
162
|
+
return onCleanup(d), d;
|
|
163
|
+
}
|
|
164
|
+
function bindTwoWay(source, dest, to = IDENTITY, from = IDENTITY) {
|
|
165
|
+
const a = bind(source, dest, to);
|
|
166
|
+
const b = bind(dest, source, from);
|
|
167
|
+
return () => (a(), b());
|
|
168
|
+
}
|
|
169
|
+
function toSetter(get, set) {
|
|
170
|
+
return (x) => {
|
|
171
|
+
const out = typeof x === "function" ? x(untrack(get)) : x;
|
|
172
|
+
return set(out), out;
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function toSignal(obj, k) {
|
|
176
|
+
const get = () => obj()[k()];
|
|
177
|
+
return [get, toSetter(get, (v) => obj()[k()] = v)];
|
|
178
|
+
}
|
|
179
|
+
function coalesceSignal([get, set], f) {
|
|
180
|
+
return [() => get() ?? set(f), set];
|
|
181
|
+
}
|
|
182
|
+
function unwrapSignal(f) {
|
|
183
|
+
return [() => f()[0](), (x) => f()[1](x)];
|
|
184
|
+
}
|
|
185
|
+
function untrackCall(f, ...args) {
|
|
186
|
+
return untrack(() => f.apply(this, args));
|
|
187
|
+
}
|
|
188
|
+
function refCall(ref, value) {
|
|
189
|
+
if (!ref)
|
|
190
|
+
return value;
|
|
191
|
+
if (typeof ref !== "function")
|
|
192
|
+
throw new ReferenceError('Il parametro "ref" deve essere stato compilato in una funzione a runtime');
|
|
193
|
+
ref(value);
|
|
194
|
+
return value;
|
|
195
|
+
}
|
|
196
|
+
function memoProps(obj, keys = Object.keys(obj)) {
|
|
197
|
+
const out = {};
|
|
198
|
+
for (const elm of keys)
|
|
199
|
+
Object.defineProperty(out, elm, {
|
|
200
|
+
enumerable: true,
|
|
201
|
+
get: createMemo(() => obj[elm])
|
|
202
|
+
});
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
205
|
+
function splitAndMemoProps(obj, keys) {
|
|
206
|
+
const out = splitProps(obj, keys);
|
|
207
|
+
out[0] = memoProps(out[0], keys);
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
function runWithContext(ctx2, value, f) {
|
|
211
|
+
return createRoot((d) => {
|
|
212
|
+
try {
|
|
213
|
+
(getOwner().context ??= {})[ctx2.id] = value;
|
|
214
|
+
return f(value === void 0 ? ctx2.defaultValue : value);
|
|
215
|
+
} finally {
|
|
216
|
+
d();
|
|
209
217
|
}
|
|
210
218
|
});
|
|
211
219
|
}
|
|
220
|
+
function createReactiveResource(f) {
|
|
221
|
+
var refetch;
|
|
222
|
+
const memo = createMemo(f);
|
|
223
|
+
createEffect(on(memo, () => refetch?.()));
|
|
224
|
+
const [get] = [, {
|
|
225
|
+
refetch
|
|
226
|
+
}] = createResource(memo);
|
|
227
|
+
return get;
|
|
228
|
+
}
|
|
212
229
|
export {
|
|
213
230
|
Case,
|
|
214
231
|
Debug,
|
|
215
|
-
|
|
232
|
+
ReactiveContext,
|
|
216
233
|
When,
|
|
217
234
|
bind,
|
|
218
235
|
bindTwoWay,
|
|
219
236
|
coalesceSignal,
|
|
220
237
|
createExtractor,
|
|
221
|
-
createOption,
|
|
222
238
|
createReactiveResource,
|
|
223
239
|
memoProps,
|
|
224
240
|
refCall,
|
|
225
|
-
runAndDispose,
|
|
226
241
|
runWithContext,
|
|
227
242
|
splitAndMemoProps,
|
|
228
243
|
toSetter,
|
package/dist/index.umd.js
CHANGED
|
@@ -2,121 +2,89 @@
|
|
|
2
2
|
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("solid-js"), require("solid-js/store")) : typeof define === "function" && define.amd ? define(["exports", "solid-js", "solid-js/store"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.solidCtrlFlow = {}, global.solidJs, global.solidJsStore));
|
|
3
3
|
})(this, function(exports2, solidJs, store) {
|
|
4
4
|
"use strict";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return f(value);
|
|
5
|
+
class ReactiveContext extends Function {
|
|
6
|
+
/** The actual {@link Context} that contains the reactive {@link Accessor} to the value */
|
|
7
|
+
/**
|
|
8
|
+
* Returns the {@link Accessor} for the value in the current {@link Owner}.
|
|
9
|
+
* It's like calling {@link useContext}
|
|
10
|
+
*/
|
|
11
|
+
get read() {
|
|
12
|
+
return solidJs.useContext(this.ctx);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Component that sets the value of the current {@link Context} for its children.
|
|
16
|
+
* If no value is provided then it will use the default value for {@link ctx}.
|
|
17
|
+
* The function is binded for the way solid compiles components inside other objects.
|
|
18
|
+
* (The value is memoized)
|
|
19
|
+
*/
|
|
20
|
+
get Provider() {
|
|
21
|
+
const {
|
|
22
|
+
ctx: ctx2
|
|
23
|
+
} = this;
|
|
24
|
+
return function(props) {
|
|
25
|
+
const memo = solidJs.createMemo(() => props.value);
|
|
26
|
+
return solidJs.createComponent(ctx2.Provider, {
|
|
27
|
+
value: memo,
|
|
28
|
+
get children() {
|
|
29
|
+
return props.children;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Executes {@link runWithContext} on the current context
|
|
36
|
+
* @param value The value for the context
|
|
37
|
+
* @param f The function to run
|
|
38
|
+
* @returns The same thing {@link f} returned
|
|
39
|
+
*/
|
|
40
|
+
runWith(value, f) {
|
|
41
|
+
return runWithContext(this.ctx, value === void 0 ? void 0 : () => value, (x) => f(x()));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Creates a {@link ReactiveContext}
|
|
45
|
+
* @param defaultValue Initial value for the context
|
|
46
|
+
* @param name Name to give to the context
|
|
47
|
+
*/
|
|
48
|
+
static create(defaultValue, name) {
|
|
49
|
+
const ctx2 = solidJs.createContext(() => defaultValue, {
|
|
50
|
+
name
|
|
52
51
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const memo = solidJs.createMemo(f);
|
|
58
|
-
solidJs.createEffect(solidJs.on(memo, () => refetch?.()));
|
|
59
|
-
const [get] = [, {
|
|
60
|
-
refetch
|
|
61
|
-
}] = solidJs.createResource(memo);
|
|
62
|
-
return get;
|
|
63
|
-
}
|
|
64
|
-
function runAndDispose(d, f) {
|
|
65
|
-
try {
|
|
66
|
-
const out = f();
|
|
67
|
-
return out instanceof Promise ? out.finally(d) : (d(), out);
|
|
68
|
-
} catch (ex) {
|
|
69
|
-
throw d(), ex;
|
|
52
|
+
const f = () => out.read();
|
|
53
|
+
f.ctx = ctx2;
|
|
54
|
+
const out = Object.setPrototypeOf(f, ReactiveContext.prototype);
|
|
55
|
+
return out;
|
|
70
56
|
}
|
|
71
57
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
const d = solidJs.createRoot((d2) => (solidJs.createRenderEffect(solidJs.on(get, (x) => set((prev) => to(x, prev)))), d2));
|
|
75
|
-
return solidJs.onCleanup(d), d;
|
|
76
|
-
}
|
|
77
|
-
function bindTwoWay(source, dest, to = IDENTITY, from = IDENTITY) {
|
|
78
|
-
const a = bind(source, dest, to);
|
|
79
|
-
const b = bind(dest, source, from);
|
|
80
|
-
return () => (a(), b());
|
|
81
|
-
}
|
|
82
|
-
function toSetter(get, set) {
|
|
83
|
-
return (x) => {
|
|
84
|
-
const out = typeof x === "function" ? x(solidJs.untrack(get)) : x;
|
|
85
|
-
return set(out), out;
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
function toSignal(obj, k) {
|
|
89
|
-
const get = () => obj()[k()];
|
|
90
|
-
return [get, toSetter(get, (v) => obj()[k()] = v)];
|
|
91
|
-
}
|
|
92
|
-
function coalesceSignal([get, set], f) {
|
|
93
|
-
return [() => get() ?? set(f), set];
|
|
94
|
-
}
|
|
95
|
-
function unwrapSignal(f) {
|
|
96
|
-
return [() => f()[0](), (x) => f()[1](x)];
|
|
97
|
-
}
|
|
98
|
-
const ctx = solidJs.createContext(() => void 0, {
|
|
99
|
-
name: "case-when"
|
|
100
|
-
});
|
|
101
|
-
function Case(props) {
|
|
102
|
-
const memo = solidJs.createMemo(() => props.value);
|
|
103
|
-
return solidJs.createComponent(ctx.Provider, {
|
|
104
|
-
value: memo,
|
|
105
|
-
get children() {
|
|
106
|
-
return props.children;
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
|
58
|
+
const ctx$1 = ReactiveContext.create(void 0, "case-when");
|
|
59
|
+
const Case = ctx$1.Provider;
|
|
110
60
|
function When(props) {
|
|
111
61
|
const [mine, other] = splitAndMemoProps(props, ["value", "pred"]);
|
|
112
|
-
const
|
|
62
|
+
const {
|
|
63
|
+
read
|
|
64
|
+
} = ctx$1;
|
|
113
65
|
const pred = (x) => mine.pred ? mine.pred(x) : x === mine.value;
|
|
114
66
|
return solidJs.createComponent(solidJs.Match, solidJs.mergeProps({
|
|
115
67
|
get when() {
|
|
116
|
-
return pred(
|
|
68
|
+
return pred(read());
|
|
117
69
|
}
|
|
118
70
|
}, other));
|
|
119
71
|
}
|
|
72
|
+
const ctx = ReactiveContext.create(false, "debug-scope");
|
|
73
|
+
function Debug(props) {
|
|
74
|
+
return solidJs.createComponent(ctx.Provider, {
|
|
75
|
+
get value() {
|
|
76
|
+
return props.value ?? true;
|
|
77
|
+
},
|
|
78
|
+
get children() {
|
|
79
|
+
return props.children;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
(function(_Debug) {
|
|
84
|
+
Object.defineProperty(Debug, "isDebug", {
|
|
85
|
+
get: () => ctx.read
|
|
86
|
+
});
|
|
87
|
+
})(Debug || (Debug = {}));
|
|
120
88
|
function createExtractor(name = "extractor") {
|
|
121
89
|
const ctx2 = solidJs.createContext(void 0, {
|
|
122
90
|
name
|
|
@@ -190,40 +158,87 @@
|
|
|
190
158
|
}
|
|
191
159
|
});
|
|
192
160
|
}
|
|
193
|
-
const
|
|
194
|
-
function
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
161
|
+
const IDENTITY = (x) => x;
|
|
162
|
+
function bind([get], [, set], to = IDENTITY) {
|
|
163
|
+
const d = solidJs.createRoot((d2) => (solidJs.createRenderEffect(solidJs.on(get, (x) => set((prev) => to(x, prev)))), d2));
|
|
164
|
+
return solidJs.onCleanup(d), d;
|
|
165
|
+
}
|
|
166
|
+
function bindTwoWay(source, dest, to = IDENTITY, from = IDENTITY) {
|
|
167
|
+
const a = bind(source, dest, to);
|
|
168
|
+
const b = bind(dest, source, from);
|
|
169
|
+
return () => (a(), b());
|
|
170
|
+
}
|
|
171
|
+
function toSetter(get, set) {
|
|
172
|
+
return (x) => {
|
|
173
|
+
const out = typeof x === "function" ? x(solidJs.untrack(get)) : x;
|
|
174
|
+
return set(out), out;
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function toSignal(obj, k) {
|
|
178
|
+
const get = () => obj()[k()];
|
|
179
|
+
return [get, toSetter(get, (v) => obj()[k()] = v)];
|
|
180
|
+
}
|
|
181
|
+
function coalesceSignal([get, set], f) {
|
|
182
|
+
return [() => get() ?? set(f), set];
|
|
183
|
+
}
|
|
184
|
+
function unwrapSignal(f) {
|
|
185
|
+
return [() => f()[0](), (x) => f()[1](x)];
|
|
186
|
+
}
|
|
187
|
+
function untrackCall(f, ...args) {
|
|
188
|
+
return solidJs.untrack(() => f.apply(this, args));
|
|
189
|
+
}
|
|
190
|
+
function refCall(ref, value) {
|
|
191
|
+
if (!ref)
|
|
192
|
+
return value;
|
|
193
|
+
if (typeof ref !== "function")
|
|
194
|
+
throw new ReferenceError('Il parametro "ref" deve essere stato compilato in una funzione a runtime');
|
|
195
|
+
ref(value);
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
function memoProps(obj, keys = Object.keys(obj)) {
|
|
199
|
+
const out = {};
|
|
200
|
+
for (const elm of keys)
|
|
201
|
+
Object.defineProperty(out, elm, {
|
|
202
|
+
enumerable: true,
|
|
203
|
+
get: solidJs.createMemo(() => obj[elm])
|
|
204
|
+
});
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
207
|
+
function splitAndMemoProps(obj, keys) {
|
|
208
|
+
const out = solidJs.splitProps(obj, keys);
|
|
209
|
+
out[0] = memoProps(out[0], keys);
|
|
210
|
+
return out;
|
|
211
|
+
}
|
|
212
|
+
function runWithContext(ctx2, value, f) {
|
|
213
|
+
return solidJs.createRoot((d) => {
|
|
214
|
+
try {
|
|
215
|
+
(solidJs.getOwner().context ??= {})[ctx2.id] = value;
|
|
216
|
+
return f(value === void 0 ? ctx2.defaultValue : value);
|
|
217
|
+
} finally {
|
|
218
|
+
d();
|
|
211
219
|
}
|
|
212
220
|
});
|
|
213
221
|
}
|
|
222
|
+
function createReactiveResource(f) {
|
|
223
|
+
var refetch;
|
|
224
|
+
const memo = solidJs.createMemo(f);
|
|
225
|
+
solidJs.createEffect(solidJs.on(memo, () => refetch?.()));
|
|
226
|
+
const [get] = [, {
|
|
227
|
+
refetch
|
|
228
|
+
}] = solidJs.createResource(memo);
|
|
229
|
+
return get;
|
|
230
|
+
}
|
|
214
231
|
exports2.Case = Case;
|
|
215
232
|
exports2.Debug = Debug;
|
|
216
|
-
exports2.
|
|
233
|
+
exports2.ReactiveContext = ReactiveContext;
|
|
217
234
|
exports2.When = When;
|
|
218
235
|
exports2.bind = bind;
|
|
219
236
|
exports2.bindTwoWay = bindTwoWay;
|
|
220
237
|
exports2.coalesceSignal = coalesceSignal;
|
|
221
238
|
exports2.createExtractor = createExtractor;
|
|
222
|
-
exports2.createOption = createOption;
|
|
223
239
|
exports2.createReactiveResource = createReactiveResource;
|
|
224
240
|
exports2.memoProps = memoProps;
|
|
225
241
|
exports2.refCall = refCall;
|
|
226
|
-
exports2.runAndDispose = runAndDispose;
|
|
227
242
|
exports2.runWithContext = runWithContext;
|
|
228
243
|
exports2.splitAndMemoProps = splitAndMemoProps;
|
|
229
244
|
exports2.toSetter = toSetter;
|
package/package.json
CHANGED
package/readMe.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
# solid-ctrl-flow
|
|
3
|
-
Control flow components for "solid-js"
|
|
3
|
+
Control flow components for "solid-js".
|
|
4
|
+
It's always under hard development
|
|
4
5
|
|
|
5
6
|
## Components
|
|
6
7
|
|
|
@@ -40,16 +41,13 @@ const value = false;
|
|
|
40
41
|
return <>
|
|
41
42
|
<Debug value={value}>
|
|
42
43
|
{/* (A LOT OF NESTING...) */}
|
|
43
|
-
<Show when={Debug.
|
|
44
|
+
<Show when={Debug.isDebug()}>
|
|
44
45
|
THIS WOULD BE VISIBLE IF "value" HAD BEEN {true}
|
|
45
46
|
</Show>
|
|
46
47
|
</Debug>
|
|
47
48
|
</>
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
### `OptionalSuspense`
|
|
51
|
-
Like a `Suspence`, but enables you to turn it off and show the loading state
|
|
52
|
-
|
|
53
51
|
### `createExtractor()`
|
|
54
52
|
Creates a context for components that may need to be out of their parent in certain conditions.
|
|
55
53
|
If you have this component
|
|
@@ -124,6 +122,15 @@ Notice that you can use a `Source` component without adding it to the DOM:
|
|
|
124
122
|
return <>Something else</>
|
|
125
123
|
```
|
|
126
124
|
|
|
125
|
+
### `ReactiveContext.create()`
|
|
126
|
+
Method that creates a reactive version of a solid `Context` with some additional built-in functionalities
|
|
127
|
+
```ts
|
|
128
|
+
const ctx = ReactiveContext.create("SOMETHING");
|
|
129
|
+
const underlyingNormalContext = ctx.ctx;
|
|
130
|
+
const valueAccessorForTheCurrentOwner = ctx.read;
|
|
131
|
+
const value = ctx();
|
|
132
|
+
```
|
|
133
|
+
|
|
127
134
|
## Bindings
|
|
128
135
|
Functions that create bindings between `Signal`s
|
|
129
136
|
|
|
@@ -160,14 +167,8 @@ Creates a partial version of an object with memoized remaining properties
|
|
|
160
167
|
### `splitAndMemoProps()`
|
|
161
168
|
Like `splitProps()` but memoizes the whole local part
|
|
162
169
|
|
|
163
|
-
### `createOption()`
|
|
164
|
-
Allows you to create simple reactive contexts; For example `Debug` is made with it
|
|
165
|
-
|
|
166
170
|
### `runWithContext()`
|
|
167
171
|
Creates a context scope that persists for the duration of a function
|
|
168
172
|
|
|
169
173
|
### `createReactiveResource()`
|
|
170
|
-
Like `createResource()` but the provided function will be reactive
|
|
171
|
-
|
|
172
|
-
### `runAndDispose()`
|
|
173
|
-
Executes a function THEN calls a dispose callback; It works with async functions too
|
|
174
|
+
Like `createResource()` but the provided function will be reactive
|