spark-plugs 0.1.0
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 +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/internals/engine.d.ts +15 -0
- package/dist/internals/engine.d.ts.map +1 -0
- package/dist/internals/engine.js +10 -0
- package/dist/internals/engine.js.map +1 -0
- package/dist/internals/fluxCapacitor.d.ts +16 -0
- package/dist/internals/fluxCapacitor.d.ts.map +1 -0
- package/dist/internals/fluxCapacitor.js +75 -0
- package/dist/internals/fluxCapacitor.js.map +1 -0
- package/dist/internals/plug.d.ts +14 -0
- package/dist/internals/plug.d.ts.map +1 -0
- package/dist/internals/plug.js +46 -0
- package/dist/internals/plug.js.map +1 -0
- package/dist/internals/shallow.d.ts +2 -0
- package/dist/internals/shallow.d.ts.map +1 -0
- package/dist/internals/shallow.js +56 -0
- package/dist/internals/shallow.js.map +1 -0
- package/dist/internals/store.d.ts +19 -0
- package/dist/internals/store.d.ts.map +1 -0
- package/dist/internals/store.js +31 -0
- package/dist/internals/store.js.map +1 -0
- package/dist/react/hooks/useFluxCapacitor.d.ts +14 -0
- package/dist/react/hooks/useFluxCapacitor.d.ts.map +1 -0
- package/dist/react/hooks/useFluxCapacitor.js +6 -0
- package/dist/react/hooks/useFluxCapacitor.js.map +1 -0
- package/dist/react/hooks/useSpark.d.ts +12 -0
- package/dist/react/hooks/useSpark.d.ts.map +1 -0
- package/dist/react/hooks/useSpark.js +170 -0
- package/dist/react/hooks/useSpark.js.map +1 -0
- package/package.json +26 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { plug, type Spark } from "./internals/plug";
|
|
2
|
+
export { Store, createStore, store } from "./internals/store";
|
|
3
|
+
export { engine, type EngineConfig } from "./internals/engine";
|
|
4
|
+
export { fluxCapacitor } from "./internals/fluxCapacitor";
|
|
5
|
+
export { shallow } from "./internals/shallow";
|
|
6
|
+
export { useSpark, type Selector, type SparkValue, } from "./react/hooks/useSpark";
|
|
7
|
+
export { useFluxCapacitor } from "./react/hooks/useFluxCapacitor";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../spark/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EACL,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,UAAU,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { plug } from "./internals/plug";
|
|
2
|
+
export { Store, createStore, store } from "./internals/store";
|
|
3
|
+
export { engine } from "./internals/engine";
|
|
4
|
+
export { fluxCapacitor } from "./internals/fluxCapacitor";
|
|
5
|
+
export { shallow } from "./internals/shallow";
|
|
6
|
+
export { useSpark, } from "./react/hooks/useSpark";
|
|
7
|
+
export { useFluxCapacitor } from "./react/hooks/useFluxCapacitor";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../spark/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAc,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAqB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EACL,QAAQ,GAGT,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SparkValue } from "../react/hooks/useSpark";
|
|
2
|
+
import { Spark } from "./plug";
|
|
3
|
+
export interface EngineConfig<T extends Spark<any>[], S> {
|
|
4
|
+
sparks: [...T];
|
|
5
|
+
selector: (...args: {
|
|
6
|
+
[K in keyof T]: SparkValue<T[K]>;
|
|
7
|
+
}) => S;
|
|
8
|
+
__isEngineConfig: true;
|
|
9
|
+
}
|
|
10
|
+
export declare function engine<S extends Spark<any>[], // S is inferred as a specific tuple type (e.g., [Spark<string>, Spark<number>])
|
|
11
|
+
R>(sparks: [...S], // Use [...S] to ensure a specific tuple type is inferred
|
|
12
|
+
selector: (...args: {
|
|
13
|
+
[K in keyof S]: SparkValue<S[K]>;
|
|
14
|
+
}) => R): EngineConfig<S, R>;
|
|
15
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../spark/internals/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAG/B,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IACrD,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACf,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAAE,KAAK,CAAC,CAAC;IAE/D,gBAAgB,EAAE,IAAI,CAAC;CACxB;AAED,wBAAgB,MAAM,CACpB,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,gFAAgF;AACxG,CAAC,EAED,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,yDAAyD;AACzE,QAAQ,EAAE,CAER,GAAG,IAAI,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,KAC1C,CAAC,GACL,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAQpB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function engine(sparks, // Use [...S] to ensure a specific tuple type is inferred
|
|
2
|
+
selector) {
|
|
3
|
+
// The function returns the strongly typed EngineConfig object
|
|
4
|
+
return {
|
|
5
|
+
sparks,
|
|
6
|
+
selector,
|
|
7
|
+
__isEngineConfig: true,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../spark/internals/engine.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,MAAM,CAIpB,MAAc,EAAE,yDAAyD;AACzE,QAGM;IAEN,8DAA8D;IAE9D,OAAO;QACL,MAAM;QACN,QAAQ;QACR,gBAAgB,EAAE,IAAI;KACd,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Spark } from "./plug";
|
|
2
|
+
type StateSnapshot = Record<string, unknown>;
|
|
3
|
+
export declare function fluxCapacitor(plugsToTrack: Spark<any>[]): {
|
|
4
|
+
engine: import("./engine").EngineConfig<[Spark<StateSnapshot[]>, Spark<number>], {
|
|
5
|
+
stateHistory: StateSnapshot[];
|
|
6
|
+
currentIndex: number;
|
|
7
|
+
canUndo: boolean;
|
|
8
|
+
canRedo: boolean;
|
|
9
|
+
setCurrentIndex: (nextIndex: number) => void;
|
|
10
|
+
resetToDefaultValues: () => void;
|
|
11
|
+
}>;
|
|
12
|
+
redo: () => void;
|
|
13
|
+
undo: () => void;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=fluxCapacitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fluxCapacitor.d.ts","sourceRoot":"","sources":["../../spark/internals/fluxCapacitor.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,EAAE,MAAM,QAAQ,CAAC;AAErC,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAK7C,wBAAgB,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE;;;;;;qCAmElB,MAAM;;;;;EA4B3C"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { engine } from "./engine";
|
|
2
|
+
import { plug } from "./plug";
|
|
3
|
+
const historyPlug = plug([]);
|
|
4
|
+
const historyIndexPlug = plug(0);
|
|
5
|
+
export function fluxCapacitor(plugsToTrack) {
|
|
6
|
+
let isTimeTraveling = false;
|
|
7
|
+
let initialState = {};
|
|
8
|
+
plugsToTrack.forEach((p) => {
|
|
9
|
+
initialState[p.id] = p.store.getStore().get(p);
|
|
10
|
+
});
|
|
11
|
+
historyPlug.store.quietlySetState({
|
|
12
|
+
key: historyPlug,
|
|
13
|
+
value: [initialState],
|
|
14
|
+
});
|
|
15
|
+
const recordCurrentState = () => {
|
|
16
|
+
if (isTimeTraveling)
|
|
17
|
+
return;
|
|
18
|
+
const currentHistory = historyPlug();
|
|
19
|
+
const currentState = {};
|
|
20
|
+
plugsToTrack.forEach((p) => {
|
|
21
|
+
currentState[p.id] = p.store.getStore().get(p);
|
|
22
|
+
});
|
|
23
|
+
const nextHistory = [...currentHistory, currentState];
|
|
24
|
+
historyPlug(nextHistory);
|
|
25
|
+
historyIndexPlug(currentHistory.length);
|
|
26
|
+
};
|
|
27
|
+
plugsToTrack.forEach((p) => p.subscribe(recordCurrentState));
|
|
28
|
+
const applySnapshot = (index) => {
|
|
29
|
+
isTimeTraveling = true;
|
|
30
|
+
const snapshot = historyPlug()[index]; // Type assertion
|
|
31
|
+
plugsToTrack.forEach((p) => {
|
|
32
|
+
if (snapshot.hasOwnProperty(p.id)) {
|
|
33
|
+
p.store.setState({ key: p, value: snapshot[p.id] });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
isTimeTraveling = false;
|
|
37
|
+
};
|
|
38
|
+
const undo = () => {
|
|
39
|
+
const currentIndex = historyIndexPlug();
|
|
40
|
+
if (currentIndex > 0) {
|
|
41
|
+
const newIndex = currentIndex - 1;
|
|
42
|
+
historyIndexPlug(newIndex);
|
|
43
|
+
applySnapshot(newIndex);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const redo = () => {
|
|
47
|
+
const currentIndex = historyIndexPlug();
|
|
48
|
+
const newIndex = currentIndex + 1;
|
|
49
|
+
if (currentIndex < historyPlug().length) {
|
|
50
|
+
historyIndexPlug(newIndex);
|
|
51
|
+
applySnapshot(newIndex);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const setCurrentIndex = (nextIndex) => {
|
|
55
|
+
historyIndexPlug(nextIndex);
|
|
56
|
+
applySnapshot(nextIndex);
|
|
57
|
+
};
|
|
58
|
+
const resetToDefaultValues = () => {
|
|
59
|
+
historyIndexPlug(0);
|
|
60
|
+
historyPlug((p) => (p === null || p === void 0 ? void 0 : p[0]) !== undefined ? [p[0]] : []);
|
|
61
|
+
applySnapshot(0);
|
|
62
|
+
};
|
|
63
|
+
const timeTravelStatusEngine = engine([historyPlug, historyIndexPlug], (history, currentIndex) => {
|
|
64
|
+
return {
|
|
65
|
+
stateHistory: history,
|
|
66
|
+
currentIndex,
|
|
67
|
+
canUndo: currentIndex !== 0,
|
|
68
|
+
canRedo: currentIndex < history.length - 1,
|
|
69
|
+
setCurrentIndex,
|
|
70
|
+
resetToDefaultValues,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
return { engine: timeTravelStatusEngine, redo, undo };
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=fluxCapacitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fluxCapacitor.js","sourceRoot":"","sources":["../../spark/internals/fluxCapacitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Store } from "./store";
|
|
2
|
+
export type PrevStateFunction<T> = (prevState: T) => T;
|
|
3
|
+
export interface Spark<T> {
|
|
4
|
+
(newValue?: T | PrevStateFunction<T>): T;
|
|
5
|
+
id: string;
|
|
6
|
+
store: Store;
|
|
7
|
+
subscribe: (subscriber: () => void) => () => void;
|
|
8
|
+
unsubscribe: (subscriber: () => void) => void;
|
|
9
|
+
quietSet: ({ value }: {
|
|
10
|
+
value: unknown;
|
|
11
|
+
}) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function plug<T>(initialValue?: T): Spark<T>;
|
|
14
|
+
//# sourceMappingURL=plug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plug.d.ts","sourceRoot":"","sources":["../../spark/internals/plug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC;AAEvD,MAAM,WAAW,KAAK,CAAC,CAAC;IACtB,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAClD,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC9C,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CACnD;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,YAkDvC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Store } from "./store";
|
|
2
|
+
export function plug(initialValue) {
|
|
3
|
+
const store = new Store();
|
|
4
|
+
// Use a fallback UUID generator for compatibility
|
|
5
|
+
function generateUUID() {
|
|
6
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
7
|
+
try {
|
|
8
|
+
return crypto.randomUUID();
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
// Fall through to fallback
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// Fallback implementation
|
|
15
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
16
|
+
const r = (Math.random() * 16) | 0;
|
|
17
|
+
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
18
|
+
return v.toString(16);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const stableId = generateUUID();
|
|
22
|
+
const spark = function (newValue) {
|
|
23
|
+
const existingStoreValue = store.getStore().get(spark);
|
|
24
|
+
if (newValue === undefined)
|
|
25
|
+
return existingStoreValue;
|
|
26
|
+
const nextState = typeof newValue === "function"
|
|
27
|
+
? newValue(existingStoreValue)
|
|
28
|
+
: newValue;
|
|
29
|
+
if (!Object.is(nextState, existingStoreValue)) {
|
|
30
|
+
store.setState({ key: spark, value: nextState });
|
|
31
|
+
}
|
|
32
|
+
return existingStoreValue;
|
|
33
|
+
};
|
|
34
|
+
spark.id = stableId;
|
|
35
|
+
spark.store = store;
|
|
36
|
+
spark.subscribe = store.subscribe;
|
|
37
|
+
spark.unsubscribe = store.unsubscribe;
|
|
38
|
+
spark.quietSet = ({ value }) => {
|
|
39
|
+
store.quietlySetState({ key: spark, value });
|
|
40
|
+
};
|
|
41
|
+
if (arguments.length > 0) {
|
|
42
|
+
store.quietlySetState({ key: spark, value: initialValue });
|
|
43
|
+
}
|
|
44
|
+
return spark;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=plug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plug.js","sourceRoot":"","sources":["../../spark/internals/plug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAahC,MAAM,UAAU,IAAI,CAAI,YAAgB;IACtC,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;IAC1B,kDAAkD;IAClD,SAAS,YAAY;QACnB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACvD,IAAI,CAAC;gBACH,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;YAC7B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,2BAA2B;YAC7B,CAAC;QACH,CAAC;QACD,0BAA0B;QAC1B,OAAO,sCAAsC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACnE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;YAC1C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,QAAQ,GAAW,YAAY,EAAE,CAAC;IAExC,MAAM,KAAK,GAAa,UAAU,QAAmC;QACnE,MAAM,kBAAkB,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,KAAK,CAAM,CAAC;QAE5D,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,kBAAkB,CAAC;QAEtD,MAAM,SAAS,GACb,OAAO,QAAQ,KAAK,UAAU;YAC5B,CAAC,CAAE,QAAiC,CAAC,kBAAkB,CAAC;YACxD,CAAC,CAAC,QAAQ,CAAC;QAEf,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,kBAAkB,CAAC,EAAE,CAAC;YAC9C,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,kBAAkB,CAAC;IAC5B,CAAC,CAAC;IAEF,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;QAC7B,KAAK,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shallow.d.ts","sourceRoot":"","sources":["../../spark/internals/shallow.ts"],"names":[],"mappings":"AAgDA,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CA0BxD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// File used from Zustand!
|
|
2
|
+
const isIterable = (obj) => Symbol.iterator in obj;
|
|
3
|
+
const hasIterableEntries = (value) =>
|
|
4
|
+
// HACK: avoid checking entries type
|
|
5
|
+
"entries" in value;
|
|
6
|
+
const compareEntries = (valueA, valueB) => {
|
|
7
|
+
const mapA = valueA instanceof Map ? valueA : new Map(valueA.entries());
|
|
8
|
+
const mapB = valueB instanceof Map ? valueB : new Map(valueB.entries());
|
|
9
|
+
if (mapA.size !== mapB.size) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
for (const [key, value] of mapA) {
|
|
13
|
+
if (!mapB.has(key) || !Object.is(value, mapB.get(key))) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
};
|
|
19
|
+
// Ordered iterables
|
|
20
|
+
const compareIterables = (valueA, valueB) => {
|
|
21
|
+
const iteratorA = valueA[Symbol.iterator]();
|
|
22
|
+
const iteratorB = valueB[Symbol.iterator]();
|
|
23
|
+
let nextA = iteratorA.next();
|
|
24
|
+
let nextB = iteratorB.next();
|
|
25
|
+
while (!nextA.done && !nextB.done) {
|
|
26
|
+
if (!Object.is(nextA.value, nextB.value)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
nextA = iteratorA.next();
|
|
30
|
+
nextB = iteratorB.next();
|
|
31
|
+
}
|
|
32
|
+
return !!nextA.done && !!nextB.done;
|
|
33
|
+
};
|
|
34
|
+
export function shallow(valueA, valueB) {
|
|
35
|
+
if (Object.is(valueA, valueB)) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
if (typeof valueA !== "object" ||
|
|
39
|
+
valueA === null ||
|
|
40
|
+
typeof valueB !== "object" ||
|
|
41
|
+
valueB === null) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (Object.getPrototypeOf(valueA) !== Object.getPrototypeOf(valueB)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (isIterable(valueA) && isIterable(valueB)) {
|
|
48
|
+
if (hasIterableEntries(valueA) && hasIterableEntries(valueB)) {
|
|
49
|
+
return compareEntries(valueA, valueB);
|
|
50
|
+
}
|
|
51
|
+
return compareIterables(valueA, valueB);
|
|
52
|
+
}
|
|
53
|
+
// assume plain objects
|
|
54
|
+
return compareEntries({ entries: () => Object.entries(valueA) }, { entries: () => Object.entries(valueB) });
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=shallow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shallow.js","sourceRoot":"","sources":["../../spark/internals/shallow.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,MAAM,UAAU,GAAG,CAAC,GAAW,EAA4B,EAAE,CAC3D,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAC;AAEzB,MAAM,kBAAkB,GAAG,CACzB,KAAwB,EAGxB,EAAE;AACF,oCAAoC;AACpC,SAAS,IAAI,KAAK,CAAC;AAErB,MAAM,cAAc,GAAG,CACrB,MAAmD,EACnD,MAAmD,EACnD,EAAE;IACF,MAAM,IAAI,GAAG,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,oBAAoB;AACpB,MAAM,gBAAgB,GAAG,CACvB,MAAyB,EACzB,MAAyB,EACzB,EAAE;IACF,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC5C,IAAI,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;QACzB,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IACD,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;AACtC,CAAC,CAAC;AAEF,MAAM,UAAU,OAAO,CAAI,MAAS,EAAE,MAAS;IAC7C,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IACE,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,KAAK,IAAI;QACf,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,KAAK,IAAI,EACf,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7C,IAAI,kBAAkB,CAAC,MAAM,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7D,OAAO,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,uBAAuB;IACvB,OAAO,cAAc,CACnB,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EACzC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAC1C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare class Store {
|
|
2
|
+
store: Map<any, unknown>;
|
|
3
|
+
subscribers: Set<() => void>;
|
|
4
|
+
getStore(): Map<any, unknown>;
|
|
5
|
+
setState({ key, value }: {
|
|
6
|
+
key: any;
|
|
7
|
+
value: unknown;
|
|
8
|
+
}): void;
|
|
9
|
+
quietlySetState({ key, value }: {
|
|
10
|
+
key: any;
|
|
11
|
+
value: unknown;
|
|
12
|
+
}): void;
|
|
13
|
+
subscribe: (subscriber: () => void) => () => void;
|
|
14
|
+
unsubscribe: (subscriber: () => void) => void;
|
|
15
|
+
clearSubscribers: () => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function createStore(): Store;
|
|
18
|
+
export declare const store: Store;
|
|
19
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../spark/internals/store.ts"],"names":[],"mappings":"AAAA,qBAAa,KAAK;IAChB,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAa;IACrC,WAAW,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,CAAa;IAEzC,QAAQ;IAIR,QAAQ,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE;IAMrD,eAAe,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE;IAI5D,SAAS,GAAI,YAAY,MAAM,IAAI,gBAMjC;IAEF,WAAW,GAAI,YAAY,MAAM,IAAI,UAEnC;IAEF,gBAAgB,aAAkC;CACnD;AAED,wBAAgB,WAAW,UAE1B;AAED,eAAO,MAAM,KAAK,OAAgB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export class Store {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.store = new Map();
|
|
4
|
+
this.subscribers = new Set();
|
|
5
|
+
this.subscribe = (subscriber) => {
|
|
6
|
+
this.subscribers.add(subscriber);
|
|
7
|
+
return () => {
|
|
8
|
+
this.unsubscribe(subscriber);
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
this.unsubscribe = (subscriber) => {
|
|
12
|
+
this.subscribers.delete(subscriber);
|
|
13
|
+
};
|
|
14
|
+
this.clearSubscribers = () => this.subscribers.clear();
|
|
15
|
+
}
|
|
16
|
+
getStore() {
|
|
17
|
+
return this.store;
|
|
18
|
+
}
|
|
19
|
+
setState({ key, value }) {
|
|
20
|
+
this.store.set(key, value);
|
|
21
|
+
this.subscribers.forEach((subscriber) => subscriber());
|
|
22
|
+
}
|
|
23
|
+
quietlySetState({ key, value }) {
|
|
24
|
+
this.store.set(key, value);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function createStore() {
|
|
28
|
+
return new Store();
|
|
29
|
+
}
|
|
30
|
+
export const store = createStore();
|
|
31
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../spark/internals/store.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,KAAK;IAAlB;QACE,UAAK,GAAsB,IAAI,GAAG,EAAE,CAAC;QACrC,gBAAW,GAAoB,IAAI,GAAG,EAAE,CAAC;QAgBzC,cAAS,GAAG,CAAC,UAAsB,EAAE,EAAE;YACrC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAEjC,OAAO,GAAG,EAAE;gBACV,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YAC/B,CAAC,CAAC;QACJ,CAAC,CAAC;QAEF,gBAAW,GAAG,CAAC,UAAsB,EAAE,EAAE;YACvC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,qBAAgB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IACpD,CAAC;IA3BC,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,QAAQ,CAAC,EAAE,GAAG,EAAE,KAAK,EAAgC;QACnD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE3B,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,eAAe,CAAC,EAAE,GAAG,EAAE,KAAK,EAAgC;QAC1D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;CAeF;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,KAAK,EAAE,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { fluxCapacitor } from "../../internals/fluxCapacitor";
|
|
2
|
+
export declare function useFluxCapacitor(timeTravelStatusEngine: ReturnType<typeof fluxCapacitor>): {
|
|
3
|
+
undo: () => void;
|
|
4
|
+
redo: () => void;
|
|
5
|
+
stateHistory: {
|
|
6
|
+
[x: string]: unknown;
|
|
7
|
+
}[];
|
|
8
|
+
currentIndex: number;
|
|
9
|
+
canUndo: boolean;
|
|
10
|
+
canRedo: boolean;
|
|
11
|
+
setCurrentIndex: (nextIndex: number) => void;
|
|
12
|
+
resetToDefaultValues: () => void;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=useFluxCapacitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFluxCapacitor.d.ts","sourceRoot":"","sources":["../../../spark/react/hooks/useFluxCapacitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAG9D,wBAAgB,gBAAgB,CAC9B,sBAAsB,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC;;;;;;;;;;;EASzD"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { useSpark } from "./useSpark";
|
|
2
|
+
export function useFluxCapacitor(timeTravelStatusEngine) {
|
|
3
|
+
const status = useSpark(timeTravelStatusEngine.engine);
|
|
4
|
+
return Object.assign(Object.assign({}, status), { undo: timeTravelStatusEngine.undo, redo: timeTravelStatusEngine.redo });
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=useFluxCapacitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFluxCapacitor.js","sourceRoot":"","sources":["../../../spark/react/hooks/useFluxCapacitor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,UAAU,gBAAgB,CAC9B,sBAAwD;IAExD,MAAM,MAAM,GAAG,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAEvD,uCACK,MAAM,KACT,IAAI,EAAE,sBAAsB,CAAC,IAAI,EACjC,IAAI,EAAE,sBAAsB,CAAC,IAAI,IACjC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EngineConfig } from "../../internals/engine";
|
|
2
|
+
import { Spark } from "../../internals/plug";
|
|
3
|
+
export type Selector<T, S> = (value: T) => S;
|
|
4
|
+
export type SparkValue<S> = S extends Spark<infer T> ? T : never;
|
|
5
|
+
export declare function useSpark<T>(spark: Spark<T>): T;
|
|
6
|
+
export declare function useSpark<T, S>(spark: Spark<T>, selector: Selector<T, S>): S;
|
|
7
|
+
export declare function useSpark<T extends Spark<any>[], R>(config: EngineConfig<T, R>): R;
|
|
8
|
+
export declare function useSpark<S extends Spark<any>[]>(sparks: [...S], selector: (...args: {
|
|
9
|
+
[K in keyof S]: SparkValue<S[K]>;
|
|
10
|
+
}) => any): any;
|
|
11
|
+
export declare function useSpark<T, S>(sparks: Spark<T>[], selector: (values: T[]) => S): S;
|
|
12
|
+
//# sourceMappingURL=useSpark.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSpark.d.ts","sourceRoot":"","sources":["../../../spark/react/hooks/useSpark.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAG7C,MAAM,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;AAC7C,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAOjE,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAGhD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;AAG7E,wBAAgB,QAAQ,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAChD,MAAM,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,GACzB,CAAC,CAAC;AAGL,wBAAgB,QAAQ,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,EAC7C,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EACd,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,KAAK,GAAG,GAC/D,GAAG,CAAC;AAGP,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAClB,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,GAC3B,CAAC,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { useCallback, useRef, useSyncExternalStore } from "react";
|
|
2
|
+
import { shallow } from "../../internals/shallow";
|
|
3
|
+
// Helper function to identify EngineConfig objects
|
|
4
|
+
const isEngineConfig = (val) => val && val.__isEngineConfig === true;
|
|
5
|
+
export function useSpark(input, selector) {
|
|
6
|
+
// Store the last computed value reference
|
|
7
|
+
const lastValueRef = useRef(undefined);
|
|
8
|
+
const activeConfig = isEngineConfig(input)
|
|
9
|
+
? input
|
|
10
|
+
: {
|
|
11
|
+
sparks: Array.isArray(input) ? input : [input],
|
|
12
|
+
selector: selector,
|
|
13
|
+
};
|
|
14
|
+
const sparksToSubscribe = Array.isArray(activeConfig.sparks)
|
|
15
|
+
? activeConfig.sparks
|
|
16
|
+
: [activeConfig.sparks];
|
|
17
|
+
const activeSelector = activeConfig.selector;
|
|
18
|
+
const subscribe = useCallback((subscriber) => {
|
|
19
|
+
const sparksToUnsubscribe = sparksToSubscribe.map((s) => s.subscribe(subscriber));
|
|
20
|
+
return () => sparksToUnsubscribe.forEach((sparkToUnsub) => sparkToUnsub());
|
|
21
|
+
}, [sparksToSubscribe]);
|
|
22
|
+
const getSnapshot = () => {
|
|
23
|
+
const values = sparksToSubscribe.map((s) => s.store.getStore().get(s));
|
|
24
|
+
if (activeSelector) {
|
|
25
|
+
const newValue = activeSelector(...values);
|
|
26
|
+
// Compare the *newly computed value* to the *last value*
|
|
27
|
+
if (Object.is(newValue, lastValueRef.current) ||
|
|
28
|
+
shallow(newValue, lastValueRef.current)) {
|
|
29
|
+
return lastValueRef.current; // Return the stable, previous reference
|
|
30
|
+
}
|
|
31
|
+
// If they are different references (or different primitives), update cache
|
|
32
|
+
lastValueRef.current = newValue;
|
|
33
|
+
return newValue;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Default case (single plug, no selector):
|
|
37
|
+
// We assume T is stable or handled by the consumer, so we just return the raw value
|
|
38
|
+
return values[0];
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const storeValue = useSyncExternalStore(subscribe, getSnapshot);
|
|
42
|
+
return storeValue;
|
|
43
|
+
}
|
|
44
|
+
// --- useSpark Implementation ---
|
|
45
|
+
// export function useSpark(
|
|
46
|
+
// // We make the implementation signature return 'any' or 'unknown' here because
|
|
47
|
+
// // TypeScript relies entirely on the overloads above for type checking the consumer code.
|
|
48
|
+
// input: Spark<any> | Spark<any>[] | EngineConfig<any, any>,
|
|
49
|
+
// selector?: Function
|
|
50
|
+
// ): any {
|
|
51
|
+
// // Explicitly set return type to any/unknown in implementation signature
|
|
52
|
+
// const isEngineConfig = (val: any): val is EngineConfig<any, any> =>
|
|
53
|
+
// val && val.__isEngineConfig === true;
|
|
54
|
+
// let sparksToSubscribe: Spark<any>[];
|
|
55
|
+
// let activeSelector: Function | undefined;
|
|
56
|
+
// if (isEngineConfig(input)) {
|
|
57
|
+
// sparksToSubscribe = Array.isArray(input.sparks)
|
|
58
|
+
// ? input.sparks
|
|
59
|
+
// : [input.sparks];
|
|
60
|
+
// activeSelector = input.selector;
|
|
61
|
+
// } else {
|
|
62
|
+
// sparksToSubscribe = Array.isArray(input) ? input : [input];
|
|
63
|
+
// activeSelector = selector;
|
|
64
|
+
// }
|
|
65
|
+
// const subscribe = useCallback(
|
|
66
|
+
// (subscriber: () => void) => {
|
|
67
|
+
// sparksToSubscribe.forEach((s) => s.subscribe(subscriber));
|
|
68
|
+
// return () => sparksToSubscribe.forEach((s) => s.unsubscribe(subscriber));
|
|
69
|
+
// },
|
|
70
|
+
// [sparksToSubscribe]
|
|
71
|
+
// );
|
|
72
|
+
// const getSnapshot = () => {
|
|
73
|
+
// console.log({ sparksToSubscribe });
|
|
74
|
+
// const values = sparksToSubscribe.map((s) => s.store.getStore().get(s));
|
|
75
|
+
// console.log({ values });
|
|
76
|
+
// if (activeSelector) {
|
|
77
|
+
// // If we have a selector, return the result of applying it
|
|
78
|
+
// return activeSelector(...values);
|
|
79
|
+
// }
|
|
80
|
+
// // THE FIX: If it was originally a single input and no selector, return the single value (values[0])
|
|
81
|
+
// // The overloads ensure that if the user calls useSpark(plug), we return T, not an array.
|
|
82
|
+
// return values[0];
|
|
83
|
+
// };
|
|
84
|
+
// const storeValue = useSyncExternalStore(subscribe, getSnapshot);
|
|
85
|
+
// return storeValue;
|
|
86
|
+
// }
|
|
87
|
+
// Another version
|
|
88
|
+
// import { useCallback, useSyncExternalStore } from "react";
|
|
89
|
+
// import { Spark } from "../../internals/plug";
|
|
90
|
+
// export type Selector<T, S> = (value: T) => S;
|
|
91
|
+
// // Define a utility type to extract the value type T from a Spark<T>
|
|
92
|
+
// export type SparkValue<S> = S extends Spark<infer T> ? T : never;
|
|
93
|
+
// // Define an overload that handles an array of arbitrary Sparks
|
|
94
|
+
// export function useSpark<S extends Spark<any>[]>(
|
|
95
|
+
// sparks: [...S],
|
|
96
|
+
// selector: (...args: { [K in keyof S]: SparkValue<S[K]> }) => any // The selector receives arguments matching the tuple types
|
|
97
|
+
// ): any;
|
|
98
|
+
// // Keep the existing single-spark and single-spark-with-selector overloads
|
|
99
|
+
// export function useSpark<T>(spark: Spark<T>): T;
|
|
100
|
+
// export function useSpark<T, S>(spark: Spark<T>, selector: (value: T) => S): S;
|
|
101
|
+
// // Keep the existing all-same-type-array overload
|
|
102
|
+
// export function useSpark<T, S>(
|
|
103
|
+
// sparks: Spark<T>[],
|
|
104
|
+
// selector: (values: T[]) => S
|
|
105
|
+
// ): S;
|
|
106
|
+
// // The implementation remains largely the same, but the types align correctly.
|
|
107
|
+
// export function useSpark(
|
|
108
|
+
// sparkOrSparks: Spark<any> | Spark<any>[],
|
|
109
|
+
// selector?: Function // Use a generic Function type for the implementation signature
|
|
110
|
+
// ) {
|
|
111
|
+
// const subscribe = useCallback(
|
|
112
|
+
// (subscriber: () => void) => {
|
|
113
|
+
// (Array.isArray(sparkOrSparks) ? sparkOrSparks : [sparkOrSparks]).forEach(
|
|
114
|
+
// (s) => s.subscribe(subscriber)
|
|
115
|
+
// );
|
|
116
|
+
// },
|
|
117
|
+
// [sparkOrSparks]
|
|
118
|
+
// ); // Added dependency to subscribe to correctly update when sparks change
|
|
119
|
+
// const getSnapshot = () => {
|
|
120
|
+
// const values = (
|
|
121
|
+
// Array.isArray(sparkOrSparks) ? sparkOrSparks : [sparkOrSparks]
|
|
122
|
+
// ).map((s) => s.store.getStore().get(s));
|
|
123
|
+
// // If the original input was a single spark, unwrap the value for selectors
|
|
124
|
+
// const finalValue = Array.isArray(sparkOrSparks) ? values : values[0];
|
|
125
|
+
// // Note: The selector expects multiple arguments when `sparkOrSparks` is an array of different types.
|
|
126
|
+
// if (selector) {
|
|
127
|
+
// // This is the key change to support your use case:
|
|
128
|
+
// // The selector is called with arguments spread out only if the input was an array of sparks.
|
|
129
|
+
// return Array.isArray(sparkOrSparks)
|
|
130
|
+
// ? selector(...values)
|
|
131
|
+
// : selector(finalValue);
|
|
132
|
+
// }
|
|
133
|
+
// return finalValue;
|
|
134
|
+
// };
|
|
135
|
+
// const storeValue = useSyncExternalStore(subscribe, getSnapshot);
|
|
136
|
+
// return storeValue;
|
|
137
|
+
// }
|
|
138
|
+
//Another version
|
|
139
|
+
// export function useSpark<T>(spark: Spark<T>): T;
|
|
140
|
+
// export function useSpark<T, S>(spark: Spark<T>, selector: Selector<T, S>): S;
|
|
141
|
+
// export function useSpark<T, S>(
|
|
142
|
+
// sparks: Spark<T>[],
|
|
143
|
+
// selector: Selector<T[], S>
|
|
144
|
+
// ): S;
|
|
145
|
+
// export function useSpark<T, S>(
|
|
146
|
+
// spark: Spark<T> | Spark<T>[],
|
|
147
|
+
// selector?: Selector<T, S>
|
|
148
|
+
// ) {
|
|
149
|
+
// const subscribe = useCallback((subscriber: () => void) => {
|
|
150
|
+
// Array.isArray(spark)
|
|
151
|
+
// ? spark.forEach((s) => s.subscribe(subscriber))
|
|
152
|
+
// : spark.subscribe(subscriber);
|
|
153
|
+
// }, []);
|
|
154
|
+
// const getSnapshot = () => {
|
|
155
|
+
// const value = Array.isArray(spark)
|
|
156
|
+
// ? spark.map((s) => s.store.getStore().get(spark) as T)
|
|
157
|
+
// : (spark.store.getStore().get(spark) as T);
|
|
158
|
+
// // const value = spark.store.getStore().get(spark) as T;
|
|
159
|
+
// console.log({ value });
|
|
160
|
+
// return selector
|
|
161
|
+
// ? Array.isArray(value)
|
|
162
|
+
// ? selector(...value)
|
|
163
|
+
// : selector(value)
|
|
164
|
+
// : value;
|
|
165
|
+
// };
|
|
166
|
+
// const storeValue = useSyncExternalStore(subscribe, getSnapshot);
|
|
167
|
+
// // const storeValue = useSyncExternalStore(spark.subscribe, getSnapshot);
|
|
168
|
+
// return storeValue;
|
|
169
|
+
// }
|
|
170
|
+
//# sourceMappingURL=useSpark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSpark.js","sourceRoot":"","sources":["../../../spark/react/hooks/useSpark.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "spark-plugs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A tiny reactive store with React hooks, time travel via a flux capacitor, and a shallow-compare selector engine.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc -p tsconfig.json",
|
|
15
|
+
"clean": "rm -rf dist",
|
|
16
|
+
"prepare": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"react": "^18.0.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/react": "^18.0.0",
|
|
23
|
+
"typescript": "^5.6.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|