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.
@@ -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,2 @@
1
+ export declare function shallow<T>(valueA: T, valueB: T): boolean;
2
+ //# sourceMappingURL=shallow.d.ts.map
@@ -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":"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"}
@@ -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
+