@slimlib/store 1.6.1 → 2.0.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/README.md +700 -129
- package/dist/index.mjs +1067 -1
- package/dist/index.mjs.map +1 -0
- package/package.json +9 -88
- package/src/computed.ts +232 -0
- package/src/core.ts +434 -0
- package/src/debug.ts +115 -0
- package/src/effect.ts +125 -0
- package/src/flags.ts +38 -0
- package/src/globals.ts +30 -0
- package/src/index.ts +9 -0
- package/src/internal-types.ts +45 -0
- package/src/scope.ts +85 -0
- package/src/signal.ts +55 -0
- package/src/state.ts +170 -0
- package/src/symbols.ts +9 -0
- package/src/types.ts +47 -0
- package/types/index.d.ts +129 -0
- package/types/index.d.ts.map +52 -0
- package/angular/package.json +0 -5
- package/core/package.json +0 -5
- package/dist/angular.cjs +0 -37
- package/dist/angular.d.ts +0 -23
- package/dist/angular.mjs +0 -33
- package/dist/angular.umd.js +0 -2
- package/dist/angular.umd.js.map +0 -1
- package/dist/core.cjs +0 -79
- package/dist/core.d.ts +0 -8
- package/dist/core.mjs +0 -76
- package/dist/index.cjs +0 -8
- package/dist/index.d.ts +0 -1
- package/dist/index.umd.js +0 -2
- package/dist/index.umd.js.map +0 -1
- package/dist/preact.cjs +0 -16
- package/dist/preact.d.ts +0 -3
- package/dist/preact.mjs +0 -13
- package/dist/preact.umd.js +0 -2
- package/dist/preact.umd.js.map +0 -1
- package/dist/react.cjs +0 -16
- package/dist/react.d.ts +0 -3
- package/dist/react.mjs +0 -13
- package/dist/react.umd.js +0 -2
- package/dist/react.umd.js.map +0 -1
- package/dist/rxjs.cjs +0 -18
- package/dist/rxjs.d.ts +0 -3
- package/dist/rxjs.mjs +0 -15
- package/dist/rxjs.umd.js +0 -2
- package/dist/rxjs.umd.js.map +0 -1
- package/dist/svelte.cjs +0 -7
- package/dist/svelte.d.ts +0 -1
- package/dist/svelte.mjs +0 -5
- package/dist/svelte.umd.js +0 -2
- package/dist/svelte.umd.js.map +0 -1
- package/preact/package.json +0 -5
- package/react/package.json +0 -5
- package/rxjs/package.json +0 -5
- package/svelte/package.json +0 -5
package/src/symbols.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Symbols for objects that ARE exposed to users
|
|
2
|
+
// These must remain symbols to avoid leaking internal implementation details
|
|
3
|
+
export const [
|
|
4
|
+
unwrap,
|
|
5
|
+
propertyDepsSymbol,
|
|
6
|
+
trackSymbol,
|
|
7
|
+
childrenSymbol,
|
|
8
|
+
// biome-ignore lint/suspicious/noSparseArray: fine
|
|
9
|
+
] = Array.from([, , , ,], Symbol) as [symbol, symbol, symbol, symbol];
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for the reactive store
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Cleanup function returned by effect callback
|
|
7
|
+
*/
|
|
8
|
+
export type EffectCleanup = () => void;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Callback function for onDispose registration
|
|
12
|
+
*/
|
|
13
|
+
export type OnDisposeCallback = (cleanup: () => void) => void;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Callback function passed to scope
|
|
17
|
+
*/
|
|
18
|
+
export type ScopeCallback = (onDispose: OnDisposeCallback) => void;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Function type for creating or disposing a scope
|
|
22
|
+
* When called with a callback, extends the scope; when called without arguments, disposes the scope
|
|
23
|
+
*/
|
|
24
|
+
export type ScopeFunction = ((callback: ScopeCallback) => Scope) & (() => void);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A reactive scope for managing effect lifecycles
|
|
28
|
+
* Scopes can be nested and automatically clean up their tracked effects when disposed
|
|
29
|
+
*/
|
|
30
|
+
export type Scope = ScopeFunction & { [key: symbol]: unknown };
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Signal type - a callable that returns the current value with a set method
|
|
34
|
+
*/
|
|
35
|
+
export type Signal<T> = (() => T) & { set: (value: T) => void };
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A computed value that automatically tracks dependencies and caches results
|
|
39
|
+
* Calling the function returns the current computed value
|
|
40
|
+
*/
|
|
41
|
+
export type Computed<T> = () => T;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* An effect is represented by its dispose function
|
|
45
|
+
* Calling this function will stop the effect and run any cleanup
|
|
46
|
+
*/
|
|
47
|
+
export type Effect = () => void;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
declare module '@slimlib/store' {
|
|
2
|
+
/**
|
|
3
|
+
* Creates a computed value that automatically tracks dependencies and caches results
|
|
4
|
+
*/
|
|
5
|
+
export const computed: <T>(getter: () => T, equals?: (a: T, b: T) => boolean) => Computed<T>;
|
|
6
|
+
/**
|
|
7
|
+
* Unwraps a proxied value to get the underlying object
|
|
8
|
+
* (Utility - not specific to push/pull phases)
|
|
9
|
+
*/
|
|
10
|
+
export const unwrapValue: <T>(value: T) => T;
|
|
11
|
+
/**
|
|
12
|
+
* Execute all pending effects immediately
|
|
13
|
+
* This function can be called to manually trigger all scheduled effects
|
|
14
|
+
* before the next microtask
|
|
15
|
+
* PULL PHASE: Executes batched effects, each effect pulls its dependencies
|
|
16
|
+
*/
|
|
17
|
+
export const flushEffects: () => void;
|
|
18
|
+
/**
|
|
19
|
+
* Execute a callback without tracking any reactive dependencies
|
|
20
|
+
* Useful when reading signals/state without creating a dependency relationship
|
|
21
|
+
* PULL PHASE: Temporarily disables dependency tracking during pull
|
|
22
|
+
*/
|
|
23
|
+
export const untracked: <T>(callback: () => T) => T;
|
|
24
|
+
/**
|
|
25
|
+
* Debug configuration flag: Warn when writing to signals/state inside a computed
|
|
26
|
+
*/
|
|
27
|
+
export const WARN_ON_WRITE_IN_COMPUTED: number;
|
|
28
|
+
/**
|
|
29
|
+
* Debug configuration flag: Suppress warning when effects are disposed by GC instead of explicitly
|
|
30
|
+
*/
|
|
31
|
+
export const SUPPRESS_EFFECT_GC_WARNING: number;
|
|
32
|
+
/**
|
|
33
|
+
* Debug configuration flag: Warn when effects are created without an active scope
|
|
34
|
+
* This is an allowed pattern, but teams may choose to enforce scope usage for better effect lifecycle management
|
|
35
|
+
*/
|
|
36
|
+
export const WARN_ON_UNTRACKED_EFFECT: number;
|
|
37
|
+
/**
|
|
38
|
+
* Configure debug behavior using a bitfield of flags
|
|
39
|
+
*/
|
|
40
|
+
export const debugConfig: (flags: number) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Creates a reactive effect that runs when dependencies change
|
|
43
|
+
*/
|
|
44
|
+
export const effect: (callback: () => void | EffectCleanup) => (() => void);
|
|
45
|
+
/**
|
|
46
|
+
* Active scope for effect tracking
|
|
47
|
+
* When set, effects created will be tracked to this scope
|
|
48
|
+
* Can be set via setActiveScope() or automatically during scope() callbacks
|
|
49
|
+
*/
|
|
50
|
+
export let activeScope: Scope | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Set the active scope for effect tracking
|
|
53
|
+
* Effects created outside of a scope() callback will be tracked to this scope
|
|
54
|
+
* Pass undefined to clear the active scope
|
|
55
|
+
*/
|
|
56
|
+
export const setActiveScope: (scope: Scope | undefined) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Set a custom scheduler function for effect execution
|
|
59
|
+
*/
|
|
60
|
+
export const setScheduler: (newScheduler: (callback: () => void) => void) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Creates a reactive scope for tracking effects
|
|
63
|
+
* Effects created within a scope callback are automatically tracked and disposed together
|
|
64
|
+
*/
|
|
65
|
+
export const scope: (callback?: ScopeCallback, parent?: Scope | undefined | null) => Scope;
|
|
66
|
+
/**
|
|
67
|
+
* Create a simple signal without an initial value
|
|
68
|
+
*/
|
|
69
|
+
export function signal<T>(): Signal<T | undefined>;
|
|
70
|
+
/**
|
|
71
|
+
* Create a simple signal with an initial value
|
|
72
|
+
*/
|
|
73
|
+
export function signal<T>(initialValue: T): Signal<T>;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a store without an initial object
|
|
76
|
+
*/
|
|
77
|
+
export function state(): object;
|
|
78
|
+
/**
|
|
79
|
+
* Creates a store with an initial object
|
|
80
|
+
*/
|
|
81
|
+
export function state<T extends object>(object: T): T;
|
|
82
|
+
/**
|
|
83
|
+
* Public types for the reactive store
|
|
84
|
+
*/
|
|
85
|
+
/**
|
|
86
|
+
* Cleanup function returned by effect callback
|
|
87
|
+
*/
|
|
88
|
+
export type EffectCleanup = () => void;
|
|
89
|
+
/**
|
|
90
|
+
* Callback function for onDispose registration
|
|
91
|
+
*/
|
|
92
|
+
export type OnDisposeCallback = (cleanup: () => void) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Callback function passed to scope
|
|
95
|
+
*/
|
|
96
|
+
export type ScopeCallback = (onDispose: OnDisposeCallback) => void;
|
|
97
|
+
/**
|
|
98
|
+
* Function type for creating or disposing a scope
|
|
99
|
+
* When called with a callback, extends the scope; when called without arguments, disposes the scope
|
|
100
|
+
*/
|
|
101
|
+
export type ScopeFunction = ((callback: ScopeCallback) => Scope) & (() => void);
|
|
102
|
+
/**
|
|
103
|
+
* A reactive scope for managing effect lifecycles
|
|
104
|
+
* Scopes can be nested and automatically clean up their tracked effects when disposed
|
|
105
|
+
*/
|
|
106
|
+
export type Scope = ScopeFunction & {
|
|
107
|
+
[key: symbol]: unknown;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Signal type - a callable that returns the current value with a set method
|
|
111
|
+
*/
|
|
112
|
+
export type Signal<T> = (() => T) & {
|
|
113
|
+
set: (value: T) => void;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* A computed value that automatically tracks dependencies and caches results
|
|
117
|
+
* Calling the function returns the current computed value
|
|
118
|
+
*/
|
|
119
|
+
export type Computed<T> = () => T;
|
|
120
|
+
/**
|
|
121
|
+
* An effect is represented by its dispose function
|
|
122
|
+
* Calling this function will stop the effect and run any cleanup
|
|
123
|
+
*/
|
|
124
|
+
export type Effect = () => void;
|
|
125
|
+
|
|
126
|
+
export {};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"file": "index.d.ts",
|
|
4
|
+
"names": [
|
|
5
|
+
"computed",
|
|
6
|
+
"unwrapValue",
|
|
7
|
+
"flushEffects",
|
|
8
|
+
"untracked",
|
|
9
|
+
"WARN_ON_WRITE_IN_COMPUTED",
|
|
10
|
+
"SUPPRESS_EFFECT_GC_WARNING",
|
|
11
|
+
"WARN_ON_UNTRACKED_EFFECT",
|
|
12
|
+
"debugConfig",
|
|
13
|
+
"effect",
|
|
14
|
+
"activeScope",
|
|
15
|
+
"setActiveScope",
|
|
16
|
+
"setScheduler",
|
|
17
|
+
"scope",
|
|
18
|
+
"signal",
|
|
19
|
+
"state",
|
|
20
|
+
"EffectCleanup",
|
|
21
|
+
"OnDisposeCallback",
|
|
22
|
+
"ScopeCallback",
|
|
23
|
+
"ScopeFunction",
|
|
24
|
+
"Scope",
|
|
25
|
+
"Signal",
|
|
26
|
+
"Computed",
|
|
27
|
+
"Effect"
|
|
28
|
+
],
|
|
29
|
+
"sources": [
|
|
30
|
+
"../src/computed.ts",
|
|
31
|
+
"../src/core.ts",
|
|
32
|
+
"../src/debug.ts",
|
|
33
|
+
"../src/effect.ts",
|
|
34
|
+
"../src/globals.ts",
|
|
35
|
+
"../src/scope.ts",
|
|
36
|
+
"../src/signal.ts",
|
|
37
|
+
"../src/state.ts",
|
|
38
|
+
"../src/types.ts"
|
|
39
|
+
],
|
|
40
|
+
"sourcesContent": [
|
|
41
|
+
null,
|
|
42
|
+
null,
|
|
43
|
+
null,
|
|
44
|
+
null,
|
|
45
|
+
null,
|
|
46
|
+
null,
|
|
47
|
+
null,
|
|
48
|
+
null,
|
|
49
|
+
null
|
|
50
|
+
],
|
|
51
|
+
"mappings": ";;;;cAyNaA,QAAQA;;;;;cCvFRC,WAAWA;;;;;;;cAqFXC,YAAYA;;;;;;cA6KZC,SAASA;;;;cC3XTC,yBAAyBA;;;;cAKzBC,0BAA0BA;;;;;cAM1BC,wBAAwBA;;;;cAUxBC,WAAWA;;;;cCZXC,MAAMA;;;;;;YCXRC,WAAWA;;;;;;cAOTC,cAAcA;;;;cAadC,YAAYA;;;;;cClBZC,KAAKA;;;;iBCGFC,MAAMA;;;;iBAANA,MAAMA;;;;iBCANC,KAAKA;;;;iBAALA,KAAKA;;;;;;;aCLTC,aAAaA;;;;aAKbC,iBAAiBA;;;;aAKjBC,aAAaA;;;;;aAMbC,aAAaA;;;;;aAMbC,KAAKA;;;;;;aAKLC,MAAMA;;;;;;;aAMNC,QAAQA;;;;;aAMRC,MAAMA"
|
|
52
|
+
}
|
package/angular/package.json
DELETED
package/core/package.json
DELETED
package/dist/angular.cjs
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var core$1 = require('@angular/core');
|
|
4
|
-
var core = require('./core.cjs');
|
|
5
|
-
|
|
6
|
-
const createStore = core.createStoreFactory(false);
|
|
7
|
-
const toSignal = (store, injector) => {
|
|
8
|
-
const cleanupRef = (injector ? injector.get : core$1.inject)(core$1.DestroyRef);
|
|
9
|
-
const state = core$1.signal(store());
|
|
10
|
-
core$1.untracked(() => {
|
|
11
|
-
cleanupRef?.onDestroy(store((value) => {
|
|
12
|
-
state.set(value);
|
|
13
|
-
}));
|
|
14
|
-
});
|
|
15
|
-
return state.asReadonly();
|
|
16
|
-
};
|
|
17
|
-
class SlimlibStore {
|
|
18
|
-
store;
|
|
19
|
-
state;
|
|
20
|
-
signal;
|
|
21
|
-
constructor(initialState) {
|
|
22
|
-
[this.state, this.store] = createStore(initialState);
|
|
23
|
-
this.signal = toSignal(this.store);
|
|
24
|
-
}
|
|
25
|
-
select(...selectors) {
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
27
|
-
const projector = selectors.pop();
|
|
28
|
-
return core$1.computed(() => {
|
|
29
|
-
const values = selectors.map(selector => selector());
|
|
30
|
-
return projector(this.signal(), ...values);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
exports.SlimlibStore = SlimlibStore;
|
|
36
|
-
exports.createStore = createStore;
|
|
37
|
-
exports.toSignal = toSignal;
|
package/dist/angular.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type ProviderToken, type Signal } from '@angular/core';
|
|
2
|
-
import { type Store } from './core';
|
|
3
|
-
export type InjectorLike = {
|
|
4
|
-
get: {
|
|
5
|
-
<T>(token: ProviderToken<T>): T;
|
|
6
|
-
};
|
|
7
|
-
};
|
|
8
|
-
export declare const createStore: <T extends object>(object?: T) => [T, Store<T>, () => void];
|
|
9
|
-
export declare const toSignal: <T>(store: Store<T>, injector?: InjectorLike) => Signal<T>;
|
|
10
|
-
type SignalValue<T extends Signal<unknown>> = T extends Signal<infer Value> ? Value : never;
|
|
11
|
-
type ArrayOfSignalValues<T extends Signal<unknown>[]> = {
|
|
12
|
-
[S in keyof T]: SignalValue<T[S]>;
|
|
13
|
-
};
|
|
14
|
-
type Prepend<I, T extends unknown[]> = [I, ...T];
|
|
15
|
-
type SignalsProjector<Signals extends Signal<unknown>[], Result, State> = (...values: Prepend<State, ArrayOfSignalValues<Signals>>) => Result;
|
|
16
|
-
export declare class SlimlibStore<T extends object> {
|
|
17
|
-
private readonly store;
|
|
18
|
-
protected readonly state: T;
|
|
19
|
-
readonly signal: Signal<T>;
|
|
20
|
-
constructor(initialState: T);
|
|
21
|
-
select<P extends Signal<unknown>[], R>(...selectors: [...signals: P, projector: SignalsProjector<P, R, T>]): Signal<R>;
|
|
22
|
-
}
|
|
23
|
-
export {};
|
package/dist/angular.mjs
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { inject, DestroyRef, signal, untracked, computed } from '@angular/core';
|
|
2
|
-
import { createStoreFactory } from './core.mjs';
|
|
3
|
-
|
|
4
|
-
const createStore = createStoreFactory(false);
|
|
5
|
-
const toSignal = (store, injector) => {
|
|
6
|
-
const cleanupRef = (injector ? injector.get : inject)(DestroyRef);
|
|
7
|
-
const state = signal(store());
|
|
8
|
-
untracked(() => {
|
|
9
|
-
cleanupRef?.onDestroy(store((value) => {
|
|
10
|
-
state.set(value);
|
|
11
|
-
}));
|
|
12
|
-
});
|
|
13
|
-
return state.asReadonly();
|
|
14
|
-
};
|
|
15
|
-
class SlimlibStore {
|
|
16
|
-
store;
|
|
17
|
-
state;
|
|
18
|
-
signal;
|
|
19
|
-
constructor(initialState) {
|
|
20
|
-
[this.state, this.store] = createStore(initialState);
|
|
21
|
-
this.signal = toSignal(this.store);
|
|
22
|
-
}
|
|
23
|
-
select(...selectors) {
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
25
|
-
const projector = selectors.pop();
|
|
26
|
-
return computed(() => {
|
|
27
|
-
const values = selectors.map(selector => selector());
|
|
28
|
-
return projector(this.signal(), ...values);
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export { SlimlibStore, createStore, toSignal };
|
package/dist/angular.umd.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("./core")):"function"==typeof define&&define.amd?define(["exports","@angular/core","./core"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).slimlibStoreAngular={},e.angularCore,e.slimlibStoreCore)}(this,(function(e,t,o){"use strict";const s=o.createStoreFactory(!1),n=(e,o)=>{const s=(o?o.get:t.inject)(t.DestroyRef),n=t.signal(e());return t.untracked((()=>{s?.onDestroy(e((e=>{n.set(e)})))})),n.asReadonly()};e.SlimlibStore=class{store;state;signal;constructor(e){[this.state,this.store]=s(e),this.signal=n(this.store)}select(...e){const o=e.pop();return t.computed((()=>{const t=e.map((e=>e()));return o(this.signal(),...t)}))}},e.createStore=s,e.toSignal=n}));
|
|
2
|
-
//# sourceMappingURL=angular.umd.js.map
|
package/dist/angular.umd.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"angular.umd.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/core.cjs
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const unwrap = Symbol();
|
|
4
|
-
const unwrapValue = (value) => (value != null && value[unwrap]) || value;
|
|
5
|
-
const createStoreFactory = (notifyAfterCreation) => {
|
|
6
|
-
return (object = {}) => {
|
|
7
|
-
let willNotifyNextTick = false;
|
|
8
|
-
const proxiesCache = new WeakMap();
|
|
9
|
-
const storeListeners = new Set();
|
|
10
|
-
const enqueueNotification = () => {
|
|
11
|
-
if (!willNotifyNextTick) {
|
|
12
|
-
willNotifyNextTick = true;
|
|
13
|
-
queueMicrotask(() => {
|
|
14
|
-
willNotifyNextTick = false;
|
|
15
|
-
for (const listener of storeListeners) {
|
|
16
|
-
listener(object);
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
const handler = {
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
-
set(target, p, value, receiver) {
|
|
24
|
-
const realValue = unwrapValue(value);
|
|
25
|
-
if (Reflect.get(target, p, receiver) !== realValue) {
|
|
26
|
-
Reflect.set(target, p, realValue, receiver);
|
|
27
|
-
enqueueNotification();
|
|
28
|
-
}
|
|
29
|
-
return true;
|
|
30
|
-
},
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
-
get(target, p, receiver) {
|
|
33
|
-
if (p === unwrap)
|
|
34
|
-
return target;
|
|
35
|
-
const value = Reflect.get(target, p, receiver);
|
|
36
|
-
return value !== null && typeof value === 'object' && !(value instanceof RegExp) ? createProxy(value) : value;
|
|
37
|
-
},
|
|
38
|
-
defineProperty(...args) {
|
|
39
|
-
enqueueNotification();
|
|
40
|
-
return Reflect.defineProperty(...args);
|
|
41
|
-
},
|
|
42
|
-
deleteProperty(target, p) {
|
|
43
|
-
const result = Reflect.deleteProperty(target, p);
|
|
44
|
-
if (result) {
|
|
45
|
-
enqueueNotification();
|
|
46
|
-
}
|
|
47
|
-
return result;
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
const proxy = createProxy(object);
|
|
51
|
-
return [
|
|
52
|
-
proxy,
|
|
53
|
-
((cb) => {
|
|
54
|
-
if (!cb) {
|
|
55
|
-
return object;
|
|
56
|
-
}
|
|
57
|
-
storeListeners.add(cb);
|
|
58
|
-
if (notifyAfterCreation) {
|
|
59
|
-
cb(object);
|
|
60
|
-
}
|
|
61
|
-
return () => storeListeners.delete(cb);
|
|
62
|
-
}),
|
|
63
|
-
enqueueNotification
|
|
64
|
-
];
|
|
65
|
-
function createProxy(object) {
|
|
66
|
-
if (proxiesCache.has(object)) {
|
|
67
|
-
return proxiesCache.get(object);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
const proxy = new Proxy(object, handler);
|
|
71
|
-
proxiesCache.set(object, proxy);
|
|
72
|
-
return proxy;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
exports.createStoreFactory = createStoreFactory;
|
|
79
|
-
exports.unwrapValue = unwrapValue;
|
package/dist/core.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export type StoreCallback<T> = (value: T) => void;
|
|
2
|
-
export type UnsubscribeCallback = () => void;
|
|
3
|
-
export interface Store<T> {
|
|
4
|
-
(cb: StoreCallback<T>): UnsubscribeCallback;
|
|
5
|
-
(): Readonly<T>;
|
|
6
|
-
}
|
|
7
|
-
export declare const unwrapValue: <T>(value: T) => T;
|
|
8
|
-
export declare const createStoreFactory: (notifyAfterCreation: boolean) => <T extends object>(object?: T) => [T, Store<T>, () => void];
|
package/dist/core.mjs
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
const unwrap = Symbol();
|
|
2
|
-
const unwrapValue = (value) => (value != null && value[unwrap]) || value;
|
|
3
|
-
const createStoreFactory = (notifyAfterCreation) => {
|
|
4
|
-
return (object = {}) => {
|
|
5
|
-
let willNotifyNextTick = false;
|
|
6
|
-
const proxiesCache = new WeakMap();
|
|
7
|
-
const storeListeners = new Set();
|
|
8
|
-
const enqueueNotification = () => {
|
|
9
|
-
if (!willNotifyNextTick) {
|
|
10
|
-
willNotifyNextTick = true;
|
|
11
|
-
queueMicrotask(() => {
|
|
12
|
-
willNotifyNextTick = false;
|
|
13
|
-
for (const listener of storeListeners) {
|
|
14
|
-
listener(object);
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
const handler = {
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
-
set(target, p, value, receiver) {
|
|
22
|
-
const realValue = unwrapValue(value);
|
|
23
|
-
if (Reflect.get(target, p, receiver) !== realValue) {
|
|
24
|
-
Reflect.set(target, p, realValue, receiver);
|
|
25
|
-
enqueueNotification();
|
|
26
|
-
}
|
|
27
|
-
return true;
|
|
28
|
-
},
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
-
get(target, p, receiver) {
|
|
31
|
-
if (p === unwrap)
|
|
32
|
-
return target;
|
|
33
|
-
const value = Reflect.get(target, p, receiver);
|
|
34
|
-
return value !== null && typeof value === 'object' && !(value instanceof RegExp) ? createProxy(value) : value;
|
|
35
|
-
},
|
|
36
|
-
defineProperty(...args) {
|
|
37
|
-
enqueueNotification();
|
|
38
|
-
return Reflect.defineProperty(...args);
|
|
39
|
-
},
|
|
40
|
-
deleteProperty(target, p) {
|
|
41
|
-
const result = Reflect.deleteProperty(target, p);
|
|
42
|
-
if (result) {
|
|
43
|
-
enqueueNotification();
|
|
44
|
-
}
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
const proxy = createProxy(object);
|
|
49
|
-
return [
|
|
50
|
-
proxy,
|
|
51
|
-
((cb) => {
|
|
52
|
-
if (!cb) {
|
|
53
|
-
return object;
|
|
54
|
-
}
|
|
55
|
-
storeListeners.add(cb);
|
|
56
|
-
if (notifyAfterCreation) {
|
|
57
|
-
cb(object);
|
|
58
|
-
}
|
|
59
|
-
return () => storeListeners.delete(cb);
|
|
60
|
-
}),
|
|
61
|
-
enqueueNotification
|
|
62
|
-
];
|
|
63
|
-
function createProxy(object) {
|
|
64
|
-
if (proxiesCache.has(object)) {
|
|
65
|
-
return proxiesCache.get(object);
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
const proxy = new Proxy(object, handler);
|
|
69
|
-
proxiesCache.set(object, proxy);
|
|
70
|
-
return proxy;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
export { createStoreFactory, unwrapValue };
|
package/dist/index.cjs
DELETED
package/dist/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './core';
|
package/dist/index.umd.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("./core")):"function"==typeof define&&define.amd?define(["exports","./core"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).slimlibStore={},e.slimlibStoreCore)}(this,(function(e,t){"use strict";Object.keys(t).forEach((function(n){"default"===n||Object.prototype.hasOwnProperty.call(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[n]}})}))}));
|
|
2
|
-
//# sourceMappingURL=index.umd.js.map
|
package/dist/index.umd.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/preact.cjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var hooks = require('preact/hooks');
|
|
4
|
-
var core = require('./core.cjs');
|
|
5
|
-
|
|
6
|
-
const createStore = core.createStoreFactory(false);
|
|
7
|
-
const useStore = (store) => {
|
|
8
|
-
const [, setState] = hooks.useState();
|
|
9
|
-
hooks.useEffect(() => {
|
|
10
|
-
return store(() => setState({}));
|
|
11
|
-
}, [store]);
|
|
12
|
-
return store();
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
exports.createStore = createStore;
|
|
16
|
-
exports.useStore = useStore;
|
package/dist/preact.d.ts
DELETED
package/dist/preact.mjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from 'preact/hooks';
|
|
2
|
-
import { createStoreFactory } from './core.mjs';
|
|
3
|
-
|
|
4
|
-
const createStore = createStoreFactory(false);
|
|
5
|
-
const useStore = (store) => {
|
|
6
|
-
const [, setState] = useState();
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
return store(() => setState({}));
|
|
9
|
-
}, [store]);
|
|
10
|
-
return store();
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export { createStore, useStore };
|
package/dist/preact.umd.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports,require("preact/hooks"),require("./core")):"function"==typeof define&&define.amd?define(["exports","preact/hooks","./core"],o):o((e="undefined"!=typeof globalThis?globalThis:e||self).slimlibStorePreact={},e.preactHooks,e.slimlibStoreCore)}(this,(function(e,o,t){"use strict";const n=t.createStoreFactory(!1);e.createStore=n,e.useStore=e=>{const[,t]=o.useState();return o.useEffect((()=>e((()=>t({})))),[e]),e()}}));
|
|
2
|
-
//# sourceMappingURL=preact.umd.js.map
|
package/dist/preact.umd.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"preact.umd.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/react.cjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var react = require('react');
|
|
4
|
-
var core = require('./core.cjs');
|
|
5
|
-
|
|
6
|
-
const createStore = core.createStoreFactory(false);
|
|
7
|
-
const useStore = (store) => {
|
|
8
|
-
const [, setState] = react.useState();
|
|
9
|
-
react.useEffect(() => {
|
|
10
|
-
return store(() => setState({}));
|
|
11
|
-
}, [store]);
|
|
12
|
-
return store();
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
exports.createStore = createStore;
|
|
16
|
-
exports.useStore = useStore;
|
package/dist/react.d.ts
DELETED
package/dist/react.mjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
import { createStoreFactory } from './core.mjs';
|
|
3
|
-
|
|
4
|
-
const createStore = createStoreFactory(false);
|
|
5
|
-
const useStore = (store) => {
|
|
6
|
-
const [, setState] = useState();
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
return store(() => setState({}));
|
|
9
|
-
}, [store]);
|
|
10
|
-
return store();
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export { createStore, useStore };
|
package/dist/react.umd.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("./core")):"function"==typeof define&&define.amd?define(["exports","react","./core"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).slimlibStoreReact={},e.react,e.slimlibStoreCore)}(this,(function(e,t,o){"use strict";const n=o.createStoreFactory(!1);e.createStore=n,e.useStore=e=>{const[,o]=t.useState();return t.useEffect((()=>e((()=>o({})))),[e]),e()}}));
|
|
2
|
-
//# sourceMappingURL=react.umd.js.map
|
package/dist/react.umd.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react.umd.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/rxjs.cjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var rxjs = require('rxjs');
|
|
4
|
-
var core = require('./core.cjs');
|
|
5
|
-
|
|
6
|
-
const createStore = core.createStoreFactory(false);
|
|
7
|
-
const toObservable = (store) => {
|
|
8
|
-
const state = new rxjs.BehaviorSubject(store());
|
|
9
|
-
state.subscribe({
|
|
10
|
-
complete: store((value) => {
|
|
11
|
-
state.next(value);
|
|
12
|
-
})
|
|
13
|
-
});
|
|
14
|
-
return state.asObservable();
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
exports.createStore = createStore;
|
|
18
|
-
exports.toObservable = toObservable;
|
package/dist/rxjs.d.ts
DELETED