solid-ctrl-flow 1.0.31 → 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 +60 -43
- package/dist/index.mjs +144 -108
- package/dist/index.umd.js +143 -107
- package/package.json +1 -1
- package/readMe.md +13 -9
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,6 +153,47 @@ 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
|
|
|
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>;
|
|
196
|
+
|
|
175
197
|
/**
|
|
176
198
|
* Executes a {@link Ref}.
|
|
177
199
|
* Throws a {@link ReferenceError} if {@link ref} its not a function at runtime (Which should never be the case thanks to the solid compiler)
|
|
@@ -181,13 +203,6 @@ export declare function memoProps<T, K extends readonly (keyof T)[] = (keyof T)[
|
|
|
181
203
|
*/
|
|
182
204
|
export declare function refCall<T, U extends T = T>(ref: Ref<T> | undefined, value: U): U;
|
|
183
205
|
|
|
184
|
-
/**
|
|
185
|
-
* Executes {@link f} and then calls {@link d} regardless of errors.
|
|
186
|
-
* If {@link f} returns a {@link Promise}, {@link d} will be called asynchronously
|
|
187
|
-
* @returns The same thing {@link f} returned
|
|
188
|
-
*/
|
|
189
|
-
export declare function runAndDispose<R>(d: () => void, f: () => R): R;
|
|
190
|
-
|
|
191
206
|
/**
|
|
192
207
|
* Executes {@link f} with the provided value for the specified {@link Context}.
|
|
193
208
|
* You can pass `undefined` to {@link value} in order to get back the default value for {@link ctx}.
|
|
@@ -197,7 +212,9 @@ export declare function runAndDispose<R>(d: () => void, f: () => R): R;
|
|
|
197
212
|
* @param f The function to run
|
|
198
213
|
* @returns The same thing {@link f} returned
|
|
199
214
|
*/
|
|
200
|
-
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;
|
|
201
218
|
|
|
202
219
|
/**
|
|
203
220
|
* Executes {@link splitProps} and memoizes the first of the two returned objects
|
|
@@ -228,7 +245,7 @@ export declare function toSignal<T, K extends keyof T>(obj: Accessor<T>, k: Acce
|
|
|
228
245
|
* @param args Arguments for calling {@link f}
|
|
229
246
|
* @returns The same thing {@link f} returned
|
|
230
247
|
*/
|
|
231
|
-
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>;
|
|
232
249
|
|
|
233
250
|
/**
|
|
234
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,20 +156,88 @@ function Joint(props) {
|
|
|
188
156
|
}
|
|
189
157
|
});
|
|
190
158
|
}
|
|
191
|
-
const
|
|
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();
|
|
217
|
+
}
|
|
218
|
+
});
|
|
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
|
+
}
|
|
192
229
|
export {
|
|
193
230
|
Case,
|
|
194
231
|
Debug,
|
|
232
|
+
ReactiveContext,
|
|
195
233
|
When,
|
|
196
234
|
bind,
|
|
197
235
|
bindTwoWay,
|
|
198
236
|
coalesceSignal,
|
|
199
237
|
createExtractor,
|
|
200
|
-
createOption,
|
|
201
238
|
createReactiveResource,
|
|
202
239
|
memoProps,
|
|
203
240
|
refCall,
|
|
204
|
-
runAndDispose,
|
|
205
241
|
runWithContext,
|
|
206
242
|
splitAndMemoProps,
|
|
207
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,19 +158,87 @@
|
|
|
190
158
|
}
|
|
191
159
|
});
|
|
192
160
|
}
|
|
193
|
-
const
|
|
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();
|
|
219
|
+
}
|
|
220
|
+
});
|
|
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
|
+
}
|
|
194
231
|
exports2.Case = Case;
|
|
195
232
|
exports2.Debug = Debug;
|
|
233
|
+
exports2.ReactiveContext = ReactiveContext;
|
|
196
234
|
exports2.When = When;
|
|
197
235
|
exports2.bind = bind;
|
|
198
236
|
exports2.bindTwoWay = bindTwoWay;
|
|
199
237
|
exports2.coalesceSignal = coalesceSignal;
|
|
200
238
|
exports2.createExtractor = createExtractor;
|
|
201
|
-
exports2.createOption = createOption;
|
|
202
239
|
exports2.createReactiveResource = createReactiveResource;
|
|
203
240
|
exports2.memoProps = memoProps;
|
|
204
241
|
exports2.refCall = refCall;
|
|
205
|
-
exports2.runAndDispose = runAndDispose;
|
|
206
242
|
exports2.runWithContext = runWithContext;
|
|
207
243
|
exports2.splitAndMemoProps = splitAndMemoProps;
|
|
208
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,7 +41,7 @@ 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>
|
|
@@ -121,6 +122,15 @@ Notice that you can use a `Source` component without adding it to the DOM:
|
|
|
121
122
|
return <>Something else</>
|
|
122
123
|
```
|
|
123
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
|
+
|
|
124
134
|
## Bindings
|
|
125
135
|
Functions that create bindings between `Signal`s
|
|
126
136
|
|
|
@@ -157,14 +167,8 @@ Creates a partial version of an object with memoized remaining properties
|
|
|
157
167
|
### `splitAndMemoProps()`
|
|
158
168
|
Like `splitProps()` but memoizes the whole local part
|
|
159
169
|
|
|
160
|
-
### `createOption()`
|
|
161
|
-
Allows you to create simple reactive contexts; For example `Debug` is made with it
|
|
162
|
-
|
|
163
170
|
### `runWithContext()`
|
|
164
171
|
Creates a context scope that persists for the duration of a function
|
|
165
172
|
|
|
166
173
|
### `createReactiveResource()`
|
|
167
|
-
Like `createResource()` but the provided function will be reactive
|
|
168
|
-
|
|
169
|
-
### `runAndDispose()`
|
|
170
|
-
Executes a function THEN calls a dispose callback; It works with async functions too
|
|
174
|
+
Like `createResource()` but the provided function will be reactive
|