@sprawlify/svelte 0.0.38
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/core/bindable.svelte.d.ts +9 -0
- package/dist/core/bindable.svelte.js +57 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +5 -0
- package/dist/core/machine.svelte.d.ts +2 -0
- package/dist/core/machine.svelte.js +260 -0
- package/dist/core/merge-props.d.ts +1 -0
- package/dist/core/merge-props.js +32 -0
- package/dist/core/normalize-props.d.ts +7 -0
- package/dist/core/normalize-props.js +43 -0
- package/dist/core/portal.d.ts +9 -0
- package/dist/core/portal.js +15 -0
- package/dist/core/reflect.d.ts +1 -0
- package/dist/core/reflect.js +11 -0
- package/dist/core/refs.svelte.d.ts +4 -0
- package/dist/core/refs.svelte.js +11 -0
- package/dist/core/track.svelte.d.ts +1 -0
- package/dist/core/track.svelte.js +28 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Bindable, BindableParams } from "@sprawlify/primitives/core";
|
|
2
|
+
export declare function bindable<T>(props: () => BindableParams<T>): Bindable<T>;
|
|
3
|
+
export declare namespace bindable {
|
|
4
|
+
var cleanup: (fn: VoidFunction) => void;
|
|
5
|
+
var ref: <T>(defaultValue: T) => {
|
|
6
|
+
get: () => T;
|
|
7
|
+
set: (next: T) => void;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { identity, isFunction } from "@sprawlify/primitives/utils";
|
|
2
|
+
import { flushSync, onDestroy, untrack } from "svelte";
|
|
3
|
+
export function bindable(props) {
|
|
4
|
+
const initial = props().defaultValue ?? props().value;
|
|
5
|
+
const eq = props().isEqual ?? Object.is;
|
|
6
|
+
let value = $state(initial);
|
|
7
|
+
const controlled = $derived(props().value !== undefined);
|
|
8
|
+
let valueRef = { current: untrack(() => value) };
|
|
9
|
+
let prevValue = { current: undefined };
|
|
10
|
+
$effect.pre(() => {
|
|
11
|
+
const v = controlled ? props().value : value;
|
|
12
|
+
valueRef = { current: v };
|
|
13
|
+
prevValue = { current: v };
|
|
14
|
+
});
|
|
15
|
+
const setValueFn = (v) => {
|
|
16
|
+
const next = isFunction(v) ? v(valueRef.current) : v;
|
|
17
|
+
const prev = prevValue.current;
|
|
18
|
+
if (props().debug) {
|
|
19
|
+
console.log(`[bindable > ${props().debug}] setValue`, { next, prev });
|
|
20
|
+
}
|
|
21
|
+
if (!controlled)
|
|
22
|
+
value = next;
|
|
23
|
+
if (!eq(next, prev)) {
|
|
24
|
+
props().onChange?.(next, prev);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function get() {
|
|
28
|
+
return (controlled ? props().value : value);
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
initial,
|
|
32
|
+
ref: valueRef,
|
|
33
|
+
get,
|
|
34
|
+
set(val) {
|
|
35
|
+
const exec = props().sync ? flushSync : identity;
|
|
36
|
+
exec(() => setValueFn(val));
|
|
37
|
+
},
|
|
38
|
+
invoke(nextValue, prevValue) {
|
|
39
|
+
props().onChange?.(nextValue, prevValue);
|
|
40
|
+
},
|
|
41
|
+
hash(value) {
|
|
42
|
+
return props().hash?.(value) ?? String(value);
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
bindable.cleanup = (fn) => {
|
|
47
|
+
onDestroy(() => fn());
|
|
48
|
+
};
|
|
49
|
+
bindable.ref = (defaultValue) => {
|
|
50
|
+
let value = defaultValue;
|
|
51
|
+
return {
|
|
52
|
+
get: () => value,
|
|
53
|
+
set: (next) => {
|
|
54
|
+
value = next;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { mergeProps } from "./merge-props";
|
|
2
|
+
export { normalizeProps } from "./normalize-props";
|
|
3
|
+
export type { PropTypes } from "./normalize-props";
|
|
4
|
+
export { portal } from "./portal";
|
|
5
|
+
export { reflect } from "./reflect";
|
|
6
|
+
export { useMachine } from "./machine.svelte";
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { createScope, INIT_STATE, MachineStatus } from "@sprawlify/primitives/core";
|
|
2
|
+
import { compact, ensure, isFunction, isString, toArray, warn } from "@sprawlify/primitives/utils";
|
|
3
|
+
import { flushSync, onDestroy, onMount } from "svelte";
|
|
4
|
+
import { bindable } from "./bindable.svelte";
|
|
5
|
+
import { useRefs } from "./refs.svelte";
|
|
6
|
+
import { track } from "./track.svelte";
|
|
7
|
+
function access(userProps) {
|
|
8
|
+
if (isFunction(userProps))
|
|
9
|
+
return userProps();
|
|
10
|
+
return userProps;
|
|
11
|
+
}
|
|
12
|
+
export function useMachine(machine, userProps) {
|
|
13
|
+
const scope = $derived.by(() => {
|
|
14
|
+
const { id, ids, getRootNode } = access(userProps);
|
|
15
|
+
return createScope({ id, ids, getRootNode });
|
|
16
|
+
});
|
|
17
|
+
const debug = (...args) => {
|
|
18
|
+
if (machine.debug)
|
|
19
|
+
console.log(...args);
|
|
20
|
+
};
|
|
21
|
+
const props = $derived(machine.props?.({ props: compact(access(userProps)), scope }) ?? access(userProps));
|
|
22
|
+
const prop = useProp(() => props);
|
|
23
|
+
const context = machine.context?.({
|
|
24
|
+
prop,
|
|
25
|
+
bindable: bindable,
|
|
26
|
+
get scope() {
|
|
27
|
+
return scope;
|
|
28
|
+
},
|
|
29
|
+
flush: flush,
|
|
30
|
+
getContext() {
|
|
31
|
+
return ctx;
|
|
32
|
+
},
|
|
33
|
+
getComputed() {
|
|
34
|
+
return computed;
|
|
35
|
+
},
|
|
36
|
+
getRefs() {
|
|
37
|
+
return refs;
|
|
38
|
+
},
|
|
39
|
+
getEvent() {
|
|
40
|
+
return getEvent();
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
const ctx = {
|
|
44
|
+
get(key) {
|
|
45
|
+
return context?.[key].get();
|
|
46
|
+
},
|
|
47
|
+
set(key, value) {
|
|
48
|
+
context?.[key].set(value);
|
|
49
|
+
},
|
|
50
|
+
initial(key) {
|
|
51
|
+
return context?.[key].initial;
|
|
52
|
+
},
|
|
53
|
+
hash(key) {
|
|
54
|
+
const current = context?.[key].get();
|
|
55
|
+
return context?.[key].hash(current);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
let effects = new Map();
|
|
59
|
+
const transitionRef = { current: null };
|
|
60
|
+
const previousEventRef = { current: null };
|
|
61
|
+
const eventRef = { current: { type: "" } };
|
|
62
|
+
const getEvent = () => ({
|
|
63
|
+
...eventRef.current,
|
|
64
|
+
current() {
|
|
65
|
+
return eventRef.current;
|
|
66
|
+
},
|
|
67
|
+
previous() {
|
|
68
|
+
return previousEventRef.current;
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
const getState = () => ({
|
|
72
|
+
...state,
|
|
73
|
+
hasTag(tag) {
|
|
74
|
+
const currentState = state.get();
|
|
75
|
+
return !!machine.states[currentState]?.tags?.includes(tag);
|
|
76
|
+
},
|
|
77
|
+
matches(...values) {
|
|
78
|
+
const currentState = state.get();
|
|
79
|
+
return values.includes(currentState);
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const refs = useRefs(machine.refs?.({ prop, context: ctx }) ?? {});
|
|
83
|
+
const getParams = () => ({
|
|
84
|
+
state: getState(),
|
|
85
|
+
context: ctx,
|
|
86
|
+
event: getEvent(),
|
|
87
|
+
prop,
|
|
88
|
+
send,
|
|
89
|
+
action,
|
|
90
|
+
guard,
|
|
91
|
+
track,
|
|
92
|
+
refs,
|
|
93
|
+
computed,
|
|
94
|
+
flush,
|
|
95
|
+
scope,
|
|
96
|
+
choose,
|
|
97
|
+
});
|
|
98
|
+
const action = (keys) => {
|
|
99
|
+
const strs = isFunction(keys) ? keys(getParams()) : keys;
|
|
100
|
+
if (!strs)
|
|
101
|
+
return;
|
|
102
|
+
const fns = strs.map((s) => {
|
|
103
|
+
const fn = machine.implementations?.actions?.[s];
|
|
104
|
+
if (!fn)
|
|
105
|
+
warn(`[zag-js] No implementation found for action "${JSON.stringify(s)}"`);
|
|
106
|
+
return fn;
|
|
107
|
+
});
|
|
108
|
+
for (const fn of fns) {
|
|
109
|
+
fn?.(getParams());
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const guard = (str) => {
|
|
113
|
+
if (isFunction(str))
|
|
114
|
+
return str(getParams());
|
|
115
|
+
return machine.implementations?.guards?.[str](getParams());
|
|
116
|
+
};
|
|
117
|
+
const effect = (keys) => {
|
|
118
|
+
const strs = isFunction(keys) ? keys(getParams()) : keys;
|
|
119
|
+
if (!strs)
|
|
120
|
+
return;
|
|
121
|
+
const fns = strs.map((s) => {
|
|
122
|
+
const fn = machine.implementations?.effects?.[s];
|
|
123
|
+
if (!fn)
|
|
124
|
+
warn(`[zag-js] No implementation found for effect "${JSON.stringify(s)}"`);
|
|
125
|
+
return fn;
|
|
126
|
+
});
|
|
127
|
+
const cleanups = [];
|
|
128
|
+
for (const fn of fns) {
|
|
129
|
+
const cleanup = fn?.(getParams());
|
|
130
|
+
if (cleanup)
|
|
131
|
+
cleanups.push(cleanup);
|
|
132
|
+
}
|
|
133
|
+
return () => cleanups.forEach((fn) => fn?.());
|
|
134
|
+
};
|
|
135
|
+
const choose = (transitions) => {
|
|
136
|
+
return toArray(transitions).find((t) => {
|
|
137
|
+
let result = !t.guard;
|
|
138
|
+
if (isString(t.guard))
|
|
139
|
+
result = !!guard(t.guard);
|
|
140
|
+
else if (isFunction(t.guard))
|
|
141
|
+
result = t.guard(getParams());
|
|
142
|
+
return result;
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
const computed = (key) => {
|
|
146
|
+
ensure(machine.computed, () => `[zag-js] No computed object found on machine`);
|
|
147
|
+
const fn = machine.computed[key];
|
|
148
|
+
return fn({
|
|
149
|
+
context: ctx,
|
|
150
|
+
event: getEvent(),
|
|
151
|
+
prop,
|
|
152
|
+
refs,
|
|
153
|
+
scope,
|
|
154
|
+
computed: computed,
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
const state = bindable(() => ({
|
|
158
|
+
defaultValue: machine.initialState({ prop }),
|
|
159
|
+
onChange(nextState, prevState) {
|
|
160
|
+
// compute effects: exit -> transition -> enter
|
|
161
|
+
// exit effects
|
|
162
|
+
if (prevState) {
|
|
163
|
+
const exitEffects = effects.get(prevState);
|
|
164
|
+
exitEffects?.();
|
|
165
|
+
effects.delete(prevState);
|
|
166
|
+
}
|
|
167
|
+
// exit actions
|
|
168
|
+
if (prevState) {
|
|
169
|
+
action(machine.states[prevState]?.exit);
|
|
170
|
+
}
|
|
171
|
+
// transition actions
|
|
172
|
+
action(transitionRef.current?.actions);
|
|
173
|
+
// enter effect
|
|
174
|
+
const cleanup = effect(machine.states[nextState]?.effects);
|
|
175
|
+
if (cleanup)
|
|
176
|
+
effects.set(nextState, cleanup);
|
|
177
|
+
// root entry actions
|
|
178
|
+
if (prevState === INIT_STATE) {
|
|
179
|
+
action(machine.entry);
|
|
180
|
+
const cleanup = effect(machine.effects);
|
|
181
|
+
if (cleanup)
|
|
182
|
+
effects.set(INIT_STATE, cleanup);
|
|
183
|
+
}
|
|
184
|
+
// enter actions
|
|
185
|
+
action(machine.states[nextState]?.entry);
|
|
186
|
+
},
|
|
187
|
+
}));
|
|
188
|
+
let status = MachineStatus.NotStarted;
|
|
189
|
+
onMount(() => {
|
|
190
|
+
const started = status === MachineStatus.Started;
|
|
191
|
+
status = MachineStatus.Started;
|
|
192
|
+
debug(started ? "rehydrating..." : "initializing...");
|
|
193
|
+
state.invoke(state.initial, INIT_STATE);
|
|
194
|
+
});
|
|
195
|
+
onDestroy(() => {
|
|
196
|
+
debug("unmounting...");
|
|
197
|
+
status = MachineStatus.Stopped;
|
|
198
|
+
effects.forEach((fn) => fn?.());
|
|
199
|
+
effects = new Map();
|
|
200
|
+
transitionRef.current = null;
|
|
201
|
+
action(machine.exit);
|
|
202
|
+
});
|
|
203
|
+
const send = (event) => {
|
|
204
|
+
if (status !== MachineStatus.Started)
|
|
205
|
+
return;
|
|
206
|
+
previousEventRef.current = eventRef.current;
|
|
207
|
+
eventRef.current = event;
|
|
208
|
+
const currentState = state.get();
|
|
209
|
+
// @ts-ignore
|
|
210
|
+
const transitions = machine.states[currentState].on?.[event.type] ?? machine.on?.[event.type];
|
|
211
|
+
const transition = choose(transitions);
|
|
212
|
+
if (!transition)
|
|
213
|
+
return;
|
|
214
|
+
// save current transition
|
|
215
|
+
transitionRef.current = transition;
|
|
216
|
+
const target = transition.target ?? currentState;
|
|
217
|
+
debug("transition", event.type, transition.target || currentState, `(${transition.actions})`);
|
|
218
|
+
const changed = target !== currentState;
|
|
219
|
+
if (changed) {
|
|
220
|
+
// state change is high priority
|
|
221
|
+
state.set(target);
|
|
222
|
+
}
|
|
223
|
+
else if (transition.reenter && !changed) {
|
|
224
|
+
// reenter will re-invoke the current state
|
|
225
|
+
state.invoke(currentState, currentState);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
// call transition actions
|
|
229
|
+
action(transition.actions);
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
machine.watch?.(getParams());
|
|
233
|
+
return {
|
|
234
|
+
get state() {
|
|
235
|
+
return getState();
|
|
236
|
+
},
|
|
237
|
+
send,
|
|
238
|
+
context: ctx,
|
|
239
|
+
prop,
|
|
240
|
+
get scope() {
|
|
241
|
+
return scope;
|
|
242
|
+
},
|
|
243
|
+
refs,
|
|
244
|
+
computed,
|
|
245
|
+
get event() {
|
|
246
|
+
return getEvent();
|
|
247
|
+
},
|
|
248
|
+
getStatus: () => status,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function useProp(value) {
|
|
252
|
+
return function get(key) {
|
|
253
|
+
return value()[key];
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function flush(fn) {
|
|
257
|
+
flushSync(() => {
|
|
258
|
+
queueMicrotask(() => fn());
|
|
259
|
+
});
|
|
260
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function mergeProps(...args: Record<string | symbol, any>[]): Record<string | symbol, any>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { mergeProps as zagMergeProps } from "@sprawlify/primitives/core";
|
|
2
|
+
import { toStyleString } from "./normalize-props";
|
|
3
|
+
const CSS_REGEX = /((?:--)?(?:\w+-?)+)\s*:\s*([^;]*)/g;
|
|
4
|
+
const serialize = (style) => {
|
|
5
|
+
const res = {};
|
|
6
|
+
let match;
|
|
7
|
+
while ((match = CSS_REGEX.exec(style))) {
|
|
8
|
+
res[match[1]] = match[2];
|
|
9
|
+
}
|
|
10
|
+
return res;
|
|
11
|
+
};
|
|
12
|
+
export function mergeProps(...args) {
|
|
13
|
+
const classNames = [];
|
|
14
|
+
for (const props of args) {
|
|
15
|
+
if (!props)
|
|
16
|
+
continue;
|
|
17
|
+
if ("class" in props && props.class != null) {
|
|
18
|
+
classNames.push(props.class);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const merged = zagMergeProps(...args);
|
|
22
|
+
if (classNames.length > 0) {
|
|
23
|
+
merged.class = classNames.length === 1 ? classNames[0] : classNames;
|
|
24
|
+
}
|
|
25
|
+
if ("style" in merged) {
|
|
26
|
+
if (typeof merged.style === "string") {
|
|
27
|
+
merged.style = serialize(merged.style);
|
|
28
|
+
}
|
|
29
|
+
merged.style = toStyleString(merged.style);
|
|
30
|
+
}
|
|
31
|
+
return merged;
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SvelteHTMLElements, HTMLAttributes } from "svelte/elements";
|
|
2
|
+
export type PropTypes = SvelteHTMLElements & {
|
|
3
|
+
element: HTMLAttributes<HTMLElement>;
|
|
4
|
+
style?: HTMLAttributes<HTMLElement>["style"] | undefined;
|
|
5
|
+
};
|
|
6
|
+
export declare function toStyleString(style: Record<string, number | string>): string;
|
|
7
|
+
export declare const normalizeProps: import("@sprawlify/primitives/types").NormalizeProps<PropTypes>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createNormalizer } from "@sprawlify/primitives/types";
|
|
2
|
+
const propMap = {
|
|
3
|
+
className: "class",
|
|
4
|
+
defaultChecked: "checked",
|
|
5
|
+
defaultValue: "value",
|
|
6
|
+
htmlFor: "for",
|
|
7
|
+
onBlur: "onfocusout",
|
|
8
|
+
onChange: "oninput",
|
|
9
|
+
onFocus: "onfocusin",
|
|
10
|
+
onDoubleClick: "ondblclick",
|
|
11
|
+
};
|
|
12
|
+
export function toStyleString(style) {
|
|
13
|
+
let string = "";
|
|
14
|
+
for (let key in style) {
|
|
15
|
+
const value = style[key];
|
|
16
|
+
if (value === null || value === undefined)
|
|
17
|
+
continue;
|
|
18
|
+
if (!key.startsWith("--"))
|
|
19
|
+
key = key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
20
|
+
string += `${key}:${value};`;
|
|
21
|
+
}
|
|
22
|
+
return string;
|
|
23
|
+
}
|
|
24
|
+
const preserveKeys = new Set("viewBox,className,preserveAspectRatio,fillRule,clipPath,clipRule,strokeWidth,strokeLinecap,strokeLinejoin,strokeDasharray,strokeDashoffset,strokeMiterlimit".split(","));
|
|
25
|
+
function toSvelteProp(key) {
|
|
26
|
+
if (key in propMap)
|
|
27
|
+
return propMap[key];
|
|
28
|
+
if (preserveKeys.has(key))
|
|
29
|
+
return key;
|
|
30
|
+
return key.toLowerCase();
|
|
31
|
+
}
|
|
32
|
+
function toSveltePropValue(key, value) {
|
|
33
|
+
if (key === "style" && typeof value === "object")
|
|
34
|
+
return toStyleString(value);
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
export const normalizeProps = createNormalizer((props) => {
|
|
38
|
+
const normalized = {};
|
|
39
|
+
for (const key in props) {
|
|
40
|
+
normalized[toSvelteProp(key)] = toSveltePropValue(key, props[key]);
|
|
41
|
+
}
|
|
42
|
+
return normalized;
|
|
43
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface PortalActionProps {
|
|
2
|
+
disabled?: boolean | undefined;
|
|
3
|
+
container?: HTMLElement | undefined;
|
|
4
|
+
getRootNode?: (() => ShadowRoot | Document | Node) | undefined;
|
|
5
|
+
}
|
|
6
|
+
export declare function portal(node: HTMLElement, props?: PortalActionProps): {
|
|
7
|
+
destroy: () => void;
|
|
8
|
+
update: (props?: PortalActionProps) => void;
|
|
9
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function portal(node, props = {}) {
|
|
2
|
+
function update(props = {}) {
|
|
3
|
+
const { container, disabled, getRootNode } = props;
|
|
4
|
+
if (disabled)
|
|
5
|
+
return;
|
|
6
|
+
const doc = getRootNode?.().ownerDocument ?? document;
|
|
7
|
+
const mountNode = container ?? doc.body;
|
|
8
|
+
mountNode.appendChild(node);
|
|
9
|
+
}
|
|
10
|
+
update(props);
|
|
11
|
+
return {
|
|
12
|
+
destroy: () => node.remove(),
|
|
13
|
+
update,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function reflect<T extends Record<string, any>>(obj: () => T): T;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const isFunction = (value) => typeof value === "function";
|
|
2
|
+
export function reflect(obj) {
|
|
3
|
+
return new Proxy(obj(), {
|
|
4
|
+
get(_, prop) {
|
|
5
|
+
const target = obj();
|
|
6
|
+
const value = Reflect.get(target, prop);
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
return isFunction(value) ? value.bind(target) : value;
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const track: (deps: any[], effect: VoidFunction) => void;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { isEqual } from "@sprawlify/primitives/utils";
|
|
2
|
+
const access = (value) => {
|
|
3
|
+
if (typeof value === "function")
|
|
4
|
+
return value();
|
|
5
|
+
return value;
|
|
6
|
+
};
|
|
7
|
+
export const track = (deps, effect) => {
|
|
8
|
+
let prevDeps = [];
|
|
9
|
+
let isFirstRun = true;
|
|
10
|
+
$effect(() => {
|
|
11
|
+
if (isFirstRun) {
|
|
12
|
+
prevDeps = deps.map((d) => access(d));
|
|
13
|
+
isFirstRun = false;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
let changed = false;
|
|
17
|
+
for (let i = 0; i < deps.length; i++) {
|
|
18
|
+
if (!isEqual(prevDeps[i], access(deps[i]))) {
|
|
19
|
+
changed = true;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (changed) {
|
|
24
|
+
prevDeps = deps.map((d) => access(d));
|
|
25
|
+
effect();
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./core";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./core";
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sprawlify/svelte",
|
|
3
|
+
"version": "0.0.38",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Svelte wrapper for primitives.",
|
|
6
|
+
"author": "sprawlify <npm@sprawlify.com>",
|
|
7
|
+
"svelte": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"svelte": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@sprawlify/primitives": "0.0.38"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"svelte": "^5.0.0"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=24"
|
|
30
|
+
},
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "svelte-kit sync && svelte-package",
|
|
34
|
+
"typecheck": "svelte-check",
|
|
35
|
+
"lint": "eslint src --fix"
|
|
36
|
+
}
|
|
37
|
+
}
|