solid-ctrl-flow 1.0.32 → 1.0.34
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 +51 -49
- package/dist/index.mjs +128 -127
- package/dist/index.umd.js +127 -126
- package/package.json +1 -1
- package/readMe.md +13 -12
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,9 @@ import { Resource } from 'solid-js';
|
|
|
7
7
|
import { Setter } from 'solid-js';
|
|
8
8
|
import { Signal } from 'solid-js';
|
|
9
9
|
|
|
10
|
+
/** Type hack for making {@link ReactiveContext} implement {@link Accessor} */
|
|
11
|
+
declare const BASE_CTOR: new <T>() => Accessor<T>;
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Creates a one-way binding between two {@link Signal}s.
|
|
12
15
|
* The function uses {@link createRenderEffect}, which means that:
|
|
@@ -64,10 +67,10 @@ export declare function bindTwoWay<S, D>(source: Signal<S>, dest: Signal<D>, to:
|
|
|
64
67
|
* <>
|
|
65
68
|
* ```
|
|
66
69
|
*/
|
|
67
|
-
export declare
|
|
70
|
+
export declare const Case: (props: {
|
|
68
71
|
value: any;
|
|
69
72
|
children: JSX.Element;
|
|
70
|
-
})
|
|
73
|
+
}) => JSX.Element;
|
|
71
74
|
|
|
72
75
|
/**
|
|
73
76
|
* Returns a {@link Signal} that applies the `??=` operator to the input one.
|
|
@@ -118,44 +121,16 @@ export declare function createExtractor(name?: string): {
|
|
|
118
121
|
readonly extracting: () => number | null;
|
|
119
122
|
};
|
|
120
123
|
|
|
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
124
|
/**
|
|
143
125
|
* 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
|
|
126
|
+
* The resource will be refetched each time one of the dependencies of {@link f} changes.
|
|
127
|
+
* The only dependant signals that will be tracked are the ones before the first `await`
|
|
145
128
|
* @param f A reactive resource fetcher
|
|
146
129
|
*/
|
|
147
130
|
export declare function createReactiveResource<R>(f: EffectFunction<R | undefined, R>): Resource<Awaited<R>>;
|
|
148
131
|
|
|
149
|
-
/**
|
|
150
|
-
export declare const
|
|
151
|
-
(props: {
|
|
152
|
-
value?: boolean | undefined;
|
|
153
|
-
children: JSX.Element;
|
|
154
|
-
}): JSX.Element;
|
|
155
|
-
runWith<V extends boolean, R>(x: V, f: (x: V) => R): R;
|
|
156
|
-
} & {
|
|
157
|
-
read: Accessor<boolean>;
|
|
158
|
-
};
|
|
132
|
+
/** Built-in {@link ReactiveContext} which allows you to display different things in debug mode */
|
|
133
|
+
export declare const debug: ReactiveContext<boolean>;
|
|
159
134
|
|
|
160
135
|
/** Informations about a {@link Source} component */
|
|
161
136
|
declare type Info = {
|
|
@@ -172,12 +147,44 @@ declare type Info = {
|
|
|
172
147
|
*/
|
|
173
148
|
export declare function memoProps<T, K extends readonly (keyof T)[] = (keyof T)[]>(obj: T, keys?: K): Pick<T, K[number]>;
|
|
174
149
|
|
|
175
|
-
/**
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
150
|
+
/**
|
|
151
|
+
* Reactive {@link Context} with some additional built-in functionalities.
|
|
152
|
+
* The call signature returns the value in the current {@link Owner} (It's like calling {@link read})
|
|
153
|
+
*/
|
|
154
|
+
export declare abstract class ReactiveContext<T> extends BASE_CTOR<T> {
|
|
155
|
+
/** The actual {@link Context} that contains the reactive {@link Accessor} to the value */
|
|
156
|
+
abstract ctx: Context<Accessor<T>>;
|
|
157
|
+
/**
|
|
158
|
+
* Returns the {@link Accessor} for the value in the current {@link Owner}.
|
|
159
|
+
* It's like calling {@link useContext}
|
|
160
|
+
*/
|
|
161
|
+
get read(): Accessor<T>;
|
|
162
|
+
/**
|
|
163
|
+
* Component that sets the value of the current {@link Context} for its children.
|
|
164
|
+
* If no value is provided then it will use the default value for {@link ctx}.
|
|
165
|
+
* The function is binded for the way solid compiles components inside other objects.
|
|
166
|
+
* (The value is memoized)
|
|
167
|
+
*/
|
|
168
|
+
get Provider(): (props: {
|
|
169
|
+
value?: T;
|
|
170
|
+
children: JSX.Element;
|
|
171
|
+
}) => JSX.Element;
|
|
172
|
+
/**
|
|
173
|
+
* Executes {@link runWithContext} on the current context
|
|
174
|
+
* @param value The value for the context
|
|
175
|
+
* @param f The function to run
|
|
176
|
+
* @returns The same thing {@link f} returned
|
|
177
|
+
*/
|
|
178
|
+
runWith<V extends T, R>(value: V, f: (x: V) => R): R;
|
|
179
|
+
runWith<R>(value: T | undefined, f: (x: T) => R): R;
|
|
180
|
+
/**
|
|
181
|
+
* Creates a {@link ReactiveContext}
|
|
182
|
+
* @param defaultValue Initial value for the context
|
|
183
|
+
* @param name Name to give to the context
|
|
184
|
+
*/
|
|
185
|
+
static create<T>(defaultValue?: undefined, name?: string): ReactiveContext<T | undefined>;
|
|
186
|
+
static create<T>(defaultValue: T, name?: string): ReactiveContext<T>;
|
|
187
|
+
}
|
|
181
188
|
|
|
182
189
|
/**
|
|
183
190
|
* Executes a {@link Ref}.
|
|
@@ -188,13 +195,6 @@ export declare function OptionalSuspense(props: {
|
|
|
188
195
|
*/
|
|
189
196
|
export declare function refCall<T, U extends T = T>(ref: Ref<T> | undefined, value: U): U;
|
|
190
197
|
|
|
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
198
|
/**
|
|
199
199
|
* Executes {@link f} with the provided value for the specified {@link Context}.
|
|
200
200
|
* You can pass `undefined` to {@link value} in order to get back the default value for {@link ctx}.
|
|
@@ -204,7 +204,9 @@ export declare function runAndDispose<R>(d: () => void, f: () => R): R;
|
|
|
204
204
|
* @param f The function to run
|
|
205
205
|
* @returns The same thing {@link f} returned
|
|
206
206
|
*/
|
|
207
|
-
export declare function runWithContext<T, R>(ctx: Context<T>, value:
|
|
207
|
+
export declare function runWithContext<T, V extends T, R>(ctx: Context<T>, value: V, f: (x: V) => R): R;
|
|
208
|
+
|
|
209
|
+
export declare function runWithContext<T, R>(ctx: Context<T>, value: T | undefined, f: (x: T) => R): R;
|
|
208
210
|
|
|
209
211
|
/**
|
|
210
212
|
* Executes {@link splitProps} and memoizes the first of the two returned objects
|
|
@@ -235,7 +237,7 @@ export declare function toSignal<T, K extends keyof T>(obj: Accessor<T>, k: Acce
|
|
|
235
237
|
* @param args Arguments for calling {@link f}
|
|
236
238
|
* @returns The same thing {@link f} returned
|
|
237
239
|
*/
|
|
238
|
-
export declare function untrackCall<F extends (...args: any[]) =>
|
|
240
|
+
export declare function untrackCall<F extends (...args: any[]) => unknown>(this: ThisParameterType<F>, f: F, ...args: Parameters<F>): ReturnType<F>;
|
|
239
241
|
|
|
240
242
|
/**
|
|
241
243
|
* Calls {@link f} maintaining its reactivity
|
package/dist/index.mjs
CHANGED
|
@@ -1,117 +1,70 @@
|
|
|
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
|
-
function
|
|
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
|
-
|
|
3
|
+
const BASE_CTOR = Function;
|
|
4
|
+
class ReactiveContext extends BASE_CTOR {
|
|
5
|
+
/** The actual {@link Context} that contains the reactive {@link Accessor} to the value */
|
|
6
|
+
/**
|
|
7
|
+
* Returns the {@link Accessor} for the value in the current {@link Owner}.
|
|
8
|
+
* It's like calling {@link useContext}
|
|
9
|
+
*/
|
|
10
|
+
get read() {
|
|
11
|
+
return useContext(this.ctx);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Component that sets the value of the current {@link Context} for its children.
|
|
15
|
+
* If no value is provided then it will use the default value for {@link ctx}.
|
|
16
|
+
* The function is binded for the way solid compiles components inside other objects.
|
|
17
|
+
* (The value is memoized)
|
|
18
|
+
*/
|
|
19
|
+
get Provider() {
|
|
20
|
+
const {
|
|
21
|
+
ctx: ctx2
|
|
22
|
+
} = this;
|
|
23
|
+
return function(props) {
|
|
24
|
+
const memo = createMemo(() => props.value);
|
|
25
|
+
return createComponent(ctx2.Provider, {
|
|
26
|
+
value: memo,
|
|
27
|
+
get children() {
|
|
28
|
+
return props.children;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Executes {@link runWithContext} on the current context
|
|
35
|
+
* @param value The value for the context
|
|
36
|
+
* @param f The function to run
|
|
37
|
+
* @returns The same thing {@link f} returned
|
|
38
|
+
*/
|
|
39
|
+
runWith(value, f) {
|
|
40
|
+
return runWithContext(this.ctx, value === void 0 ? void 0 : () => value, (x) => f(x()));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates a {@link ReactiveContext}
|
|
44
|
+
* @param defaultValue Initial value for the context
|
|
45
|
+
* @param name Name to give to the context
|
|
46
|
+
*/
|
|
47
|
+
static create(defaultValue, name) {
|
|
48
|
+
const ctx2 = createContext(() => defaultValue, {
|
|
49
|
+
name
|
|
50
50
|
});
|
|
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;
|
|
51
|
+
const f = () => out.read();
|
|
52
|
+
f.ctx = ctx2;
|
|
53
|
+
const out = Object.setPrototypeOf(f, ReactiveContext.prototype);
|
|
54
|
+
return out;
|
|
68
55
|
}
|
|
69
56
|
}
|
|
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
|
-
}
|
|
57
|
+
const ctx = ReactiveContext.create(void 0, "case-when");
|
|
58
|
+
const Case = ctx.Provider;
|
|
108
59
|
function When(props) {
|
|
109
60
|
const [mine, other] = splitAndMemoProps(props, ["value", "pred"]);
|
|
110
|
-
const
|
|
61
|
+
const {
|
|
62
|
+
read
|
|
63
|
+
} = ctx;
|
|
111
64
|
const pred = (x) => mine.pred ? mine.pred(x) : x === mine.value;
|
|
112
65
|
return createComponent(Match, mergeProps({
|
|
113
66
|
get when() {
|
|
114
|
-
return pred(
|
|
67
|
+
return pred(read());
|
|
115
68
|
}
|
|
116
69
|
}, other));
|
|
117
70
|
}
|
|
@@ -188,41 +141,89 @@ function Joint(props) {
|
|
|
188
141
|
}
|
|
189
142
|
});
|
|
190
143
|
}
|
|
191
|
-
const
|
|
192
|
-
function
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
144
|
+
const IDENTITY = (x) => x;
|
|
145
|
+
function bind([get], [, set], to = IDENTITY) {
|
|
146
|
+
const d = createRoot((d2) => (createRenderEffect(on(get, (x) => set((prev) => to(x, prev)))), d2));
|
|
147
|
+
return onCleanup(d), d;
|
|
148
|
+
}
|
|
149
|
+
function bindTwoWay(source, dest, to = IDENTITY, from = IDENTITY) {
|
|
150
|
+
const a = bind(source, dest, to);
|
|
151
|
+
const b = bind(dest, source, from);
|
|
152
|
+
return () => (a(), b());
|
|
153
|
+
}
|
|
154
|
+
function toSetter(get, set) {
|
|
155
|
+
return (x) => {
|
|
156
|
+
const out = typeof x === "function" ? x(untrack(get)) : x;
|
|
157
|
+
return set(out), out;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function toSignal(obj, k) {
|
|
161
|
+
const get = () => obj()[k()];
|
|
162
|
+
return [get, toSetter(get, (v) => obj()[k()] = v)];
|
|
163
|
+
}
|
|
164
|
+
function coalesceSignal([get, set], f) {
|
|
165
|
+
return [() => get() ?? set(f), set];
|
|
166
|
+
}
|
|
167
|
+
function unwrapSignal(f) {
|
|
168
|
+
return [() => f()[0](), (x) => f()[1](x)];
|
|
169
|
+
}
|
|
170
|
+
function untrackCall(f, ...args) {
|
|
171
|
+
return untrack(() => f.apply(this, args));
|
|
172
|
+
}
|
|
173
|
+
function refCall(ref, value) {
|
|
174
|
+
if (!ref)
|
|
175
|
+
return value;
|
|
176
|
+
if (typeof ref !== "function")
|
|
177
|
+
throw new ReferenceError('Il parametro "ref" deve essere stato compilato in una funzione a runtime');
|
|
178
|
+
ref(value);
|
|
179
|
+
return value;
|
|
180
|
+
}
|
|
181
|
+
function memoProps(obj, keys = Object.keys(obj)) {
|
|
182
|
+
const out = {};
|
|
183
|
+
for (const elm of keys)
|
|
184
|
+
Object.defineProperty(out, elm, {
|
|
185
|
+
enumerable: true,
|
|
186
|
+
get: createMemo(() => obj[elm])
|
|
187
|
+
});
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
function splitAndMemoProps(obj, keys) {
|
|
191
|
+
const out = splitProps(obj, keys);
|
|
192
|
+
out[0] = memoProps(out[0], keys);
|
|
193
|
+
return out;
|
|
194
|
+
}
|
|
195
|
+
function runWithContext(ctx2, value, f) {
|
|
196
|
+
return createRoot((d) => {
|
|
197
|
+
try {
|
|
198
|
+
(getOwner().context ??= {})[ctx2.id] = value;
|
|
199
|
+
return f(value === void 0 ? ctx2.defaultValue : value);
|
|
200
|
+
} finally {
|
|
201
|
+
d();
|
|
209
202
|
}
|
|
210
203
|
});
|
|
211
204
|
}
|
|
205
|
+
function createReactiveResource(f) {
|
|
206
|
+
var refetch;
|
|
207
|
+
const memo = createMemo(f);
|
|
208
|
+
createEffect(on(memo, () => refetch?.()));
|
|
209
|
+
const [get] = [, {
|
|
210
|
+
refetch
|
|
211
|
+
}] = createResource(memo);
|
|
212
|
+
return get;
|
|
213
|
+
}
|
|
214
|
+
const debug = ReactiveContext.create(false, "debug-scope");
|
|
212
215
|
export {
|
|
213
216
|
Case,
|
|
214
|
-
|
|
215
|
-
OptionalSuspense,
|
|
217
|
+
ReactiveContext,
|
|
216
218
|
When,
|
|
217
219
|
bind,
|
|
218
220
|
bindTwoWay,
|
|
219
221
|
coalesceSignal,
|
|
220
222
|
createExtractor,
|
|
221
|
-
createOption,
|
|
222
223
|
createReactiveResource,
|
|
224
|
+
debug,
|
|
223
225
|
memoProps,
|
|
224
226
|
refCall,
|
|
225
|
-
runAndDispose,
|
|
226
227
|
runWithContext,
|
|
227
228
|
splitAndMemoProps,
|
|
228
229
|
toSetter,
|
package/dist/index.umd.js
CHANGED
|
@@ -2,118 +2,71 @@
|
|
|
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
|
-
|
|
5
|
+
const BASE_CTOR = Function;
|
|
6
|
+
class ReactiveContext extends BASE_CTOR {
|
|
7
|
+
/** The actual {@link Context} that contains the reactive {@link Accessor} to the value */
|
|
8
|
+
/**
|
|
9
|
+
* Returns the {@link Accessor} for the value in the current {@link Owner}.
|
|
10
|
+
* It's like calling {@link useContext}
|
|
11
|
+
*/
|
|
12
|
+
get read() {
|
|
13
|
+
return solidJs.useContext(this.ctx);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Component that sets the value of the current {@link Context} for its children.
|
|
17
|
+
* If no value is provided then it will use the default value for {@link ctx}.
|
|
18
|
+
* The function is binded for the way solid compiles components inside other objects.
|
|
19
|
+
* (The value is memoized)
|
|
20
|
+
*/
|
|
21
|
+
get Provider() {
|
|
22
|
+
const {
|
|
23
|
+
ctx: ctx2
|
|
24
|
+
} = this;
|
|
25
|
+
return function(props) {
|
|
26
|
+
const memo = solidJs.createMemo(() => props.value);
|
|
27
|
+
return solidJs.createComponent(ctx2.Provider, {
|
|
28
|
+
value: memo,
|
|
29
|
+
get children() {
|
|
30
|
+
return props.children;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Executes {@link runWithContext} on the current context
|
|
37
|
+
* @param value The value for the context
|
|
38
|
+
* @param f The function to run
|
|
39
|
+
* @returns The same thing {@link f} returned
|
|
40
|
+
*/
|
|
41
|
+
runWith(value, f) {
|
|
42
|
+
return runWithContext(this.ctx, value === void 0 ? void 0 : () => value, (x) => f(x()));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a {@link ReactiveContext}
|
|
46
|
+
* @param defaultValue Initial value for the context
|
|
47
|
+
* @param name Name to give to the context
|
|
48
|
+
*/
|
|
49
|
+
static create(defaultValue, name) {
|
|
50
|
+
const ctx2 = solidJs.createContext(() => defaultValue, {
|
|
51
|
+
name
|
|
52
52
|
});
|
|
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;
|
|
53
|
+
const f = () => out.read();
|
|
54
|
+
f.ctx = ctx2;
|
|
55
|
+
const out = Object.setPrototypeOf(f, ReactiveContext.prototype);
|
|
56
|
+
return out;
|
|
70
57
|
}
|
|
71
58
|
}
|
|
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
|
-
}
|
|
59
|
+
const ctx = ReactiveContext.create(void 0, "case-when");
|
|
60
|
+
const Case = ctx.Provider;
|
|
110
61
|
function When(props) {
|
|
111
62
|
const [mine, other] = splitAndMemoProps(props, ["value", "pred"]);
|
|
112
|
-
const
|
|
63
|
+
const {
|
|
64
|
+
read
|
|
65
|
+
} = ctx;
|
|
113
66
|
const pred = (x) => mine.pred ? mine.pred(x) : x === mine.value;
|
|
114
67
|
return solidJs.createComponent(solidJs.Match, solidJs.mergeProps({
|
|
115
68
|
get when() {
|
|
116
|
-
return pred(
|
|
69
|
+
return pred(read());
|
|
117
70
|
}
|
|
118
71
|
}, other));
|
|
119
72
|
}
|
|
@@ -190,40 +143,88 @@
|
|
|
190
143
|
}
|
|
191
144
|
});
|
|
192
145
|
}
|
|
193
|
-
const
|
|
194
|
-
function
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
146
|
+
const IDENTITY = (x) => x;
|
|
147
|
+
function bind([get], [, set], to = IDENTITY) {
|
|
148
|
+
const d = solidJs.createRoot((d2) => (solidJs.createRenderEffect(solidJs.on(get, (x) => set((prev) => to(x, prev)))), d2));
|
|
149
|
+
return solidJs.onCleanup(d), d;
|
|
150
|
+
}
|
|
151
|
+
function bindTwoWay(source, dest, to = IDENTITY, from = IDENTITY) {
|
|
152
|
+
const a = bind(source, dest, to);
|
|
153
|
+
const b = bind(dest, source, from);
|
|
154
|
+
return () => (a(), b());
|
|
155
|
+
}
|
|
156
|
+
function toSetter(get, set) {
|
|
157
|
+
return (x) => {
|
|
158
|
+
const out = typeof x === "function" ? x(solidJs.untrack(get)) : x;
|
|
159
|
+
return set(out), out;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function toSignal(obj, k) {
|
|
163
|
+
const get = () => obj()[k()];
|
|
164
|
+
return [get, toSetter(get, (v) => obj()[k()] = v)];
|
|
165
|
+
}
|
|
166
|
+
function coalesceSignal([get, set], f) {
|
|
167
|
+
return [() => get() ?? set(f), set];
|
|
168
|
+
}
|
|
169
|
+
function unwrapSignal(f) {
|
|
170
|
+
return [() => f()[0](), (x) => f()[1](x)];
|
|
171
|
+
}
|
|
172
|
+
function untrackCall(f, ...args) {
|
|
173
|
+
return solidJs.untrack(() => f.apply(this, args));
|
|
174
|
+
}
|
|
175
|
+
function refCall(ref, value) {
|
|
176
|
+
if (!ref)
|
|
177
|
+
return value;
|
|
178
|
+
if (typeof ref !== "function")
|
|
179
|
+
throw new ReferenceError('Il parametro "ref" deve essere stato compilato in una funzione a runtime');
|
|
180
|
+
ref(value);
|
|
181
|
+
return value;
|
|
182
|
+
}
|
|
183
|
+
function memoProps(obj, keys = Object.keys(obj)) {
|
|
184
|
+
const out = {};
|
|
185
|
+
for (const elm of keys)
|
|
186
|
+
Object.defineProperty(out, elm, {
|
|
187
|
+
enumerable: true,
|
|
188
|
+
get: solidJs.createMemo(() => obj[elm])
|
|
189
|
+
});
|
|
190
|
+
return out;
|
|
191
|
+
}
|
|
192
|
+
function splitAndMemoProps(obj, keys) {
|
|
193
|
+
const out = solidJs.splitProps(obj, keys);
|
|
194
|
+
out[0] = memoProps(out[0], keys);
|
|
195
|
+
return out;
|
|
196
|
+
}
|
|
197
|
+
function runWithContext(ctx2, value, f) {
|
|
198
|
+
return solidJs.createRoot((d) => {
|
|
199
|
+
try {
|
|
200
|
+
(solidJs.getOwner().context ??= {})[ctx2.id] = value;
|
|
201
|
+
return f(value === void 0 ? ctx2.defaultValue : value);
|
|
202
|
+
} finally {
|
|
203
|
+
d();
|
|
211
204
|
}
|
|
212
205
|
});
|
|
213
206
|
}
|
|
207
|
+
function createReactiveResource(f) {
|
|
208
|
+
var refetch;
|
|
209
|
+
const memo = solidJs.createMemo(f);
|
|
210
|
+
solidJs.createEffect(solidJs.on(memo, () => refetch?.()));
|
|
211
|
+
const [get] = [, {
|
|
212
|
+
refetch
|
|
213
|
+
}] = solidJs.createResource(memo);
|
|
214
|
+
return get;
|
|
215
|
+
}
|
|
216
|
+
const debug = ReactiveContext.create(false, "debug-scope");
|
|
214
217
|
exports2.Case = Case;
|
|
215
|
-
exports2.
|
|
216
|
-
exports2.OptionalSuspense = OptionalSuspense;
|
|
218
|
+
exports2.ReactiveContext = ReactiveContext;
|
|
217
219
|
exports2.When = When;
|
|
218
220
|
exports2.bind = bind;
|
|
219
221
|
exports2.bindTwoWay = bindTwoWay;
|
|
220
222
|
exports2.coalesceSignal = coalesceSignal;
|
|
221
223
|
exports2.createExtractor = createExtractor;
|
|
222
|
-
exports2.createOption = createOption;
|
|
223
224
|
exports2.createReactiveResource = createReactiveResource;
|
|
225
|
+
exports2.debug = debug;
|
|
224
226
|
exports2.memoProps = memoProps;
|
|
225
227
|
exports2.refCall = refCall;
|
|
226
|
-
exports2.runAndDispose = runAndDispose;
|
|
227
228
|
exports2.runWithContext = runWithContext;
|
|
228
229
|
exports2.splitAndMemoProps = splitAndMemoProps;
|
|
229
230
|
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
|