joopjs 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/CHANGELOG.md +678 -0
- package/README.md +583 -0
- package/dist/a11y.service-C-DQQfgO.d.mts +143 -0
- package/dist/a11y.service-CauEJrJe.d.ts +143 -0
- package/dist/adapters-B6slG6hQ.d.mts +84 -0
- package/dist/adapters-B6slG6hQ.d.ts +84 -0
- package/dist/aes.service-CkoupAww.d.mts +95 -0
- package/dist/aes.service-CkoupAww.d.ts +95 -0
- package/dist/ai/index.d.mts +99 -0
- package/dist/ai/index.d.ts +99 -0
- package/dist/ai/index.js +307 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/index.mjs +304 -0
- package/dist/ai/index.mjs.map +1 -0
- package/dist/analytics/index.d.mts +42 -0
- package/dist/analytics/index.d.ts +42 -0
- package/dist/analytics/index.js +139 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/index.mjs +136 -0
- package/dist/analytics/index.mjs.map +1 -0
- package/dist/angular/index.d.mts +148 -0
- package/dist/angular/index.d.ts +148 -0
- package/dist/angular/index.js +122 -0
- package/dist/angular/index.js.map +1 -0
- package/dist/angular/index.mjs +101 -0
- package/dist/angular/index.mjs.map +1 -0
- package/dist/api/index.d.mts +128 -0
- package/dist/api/index.d.ts +128 -0
- package/dist/api/index.js +1358 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/index.mjs +1332 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/auth/index.d.mts +105 -0
- package/dist/auth/index.d.ts +105 -0
- package/dist/auth/index.js +989 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +979 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/auth.service-DNVB-L4U.d.mts +16 -0
- package/dist/auth.service-PjUUSUIt.d.ts +16 -0
- package/dist/banking/index.d.mts +1530 -0
- package/dist/banking/index.d.ts +1530 -0
- package/dist/banking/index.js +4739 -0
- package/dist/banking/index.js.map +1 -0
- package/dist/banking/index.mjs +4661 -0
- package/dist/banking/index.mjs.map +1 -0
- package/dist/cache/index.d.mts +40 -0
- package/dist/cache/index.d.ts +40 -0
- package/dist/cache/index.js +174 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/index.mjs +172 -0
- package/dist/cache/index.mjs.map +1 -0
- package/dist/client-profile.service-BuPeXVp5.d.mts +28 -0
- package/dist/client-profile.service-D5bRRYQp.d.ts +28 -0
- package/dist/config.models-Cqg04fAQ.d.mts +84 -0
- package/dist/config.models-Cqg04fAQ.d.ts +84 -0
- package/dist/config.service-CrCvI-JS.d.ts +31 -0
- package/dist/config.service-Cz4QQLlf.d.mts +31 -0
- package/dist/core/index.d.mts +4 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +631 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +619 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/crypto-utils-DriNhLdx.d.mts +30 -0
- package/dist/crypto-utils-DriNhLdx.d.ts +30 -0
- package/dist/data-storage.service-DT6xaTxE.d.ts +51 -0
- package/dist/data-storage.service-LvhGRCmw.d.mts +51 -0
- package/dist/deeplink/index.d.mts +39 -0
- package/dist/deeplink/index.d.ts +39 -0
- package/dist/deeplink/index.js +268 -0
- package/dist/deeplink/index.js.map +1 -0
- package/dist/deeplink/index.mjs +265 -0
- package/dist/deeplink/index.mjs.map +1 -0
- package/dist/deeplink.service-Ctd5u243.d.mts +35 -0
- package/dist/deeplink.service-uUuTnY9_.d.ts +35 -0
- package/dist/dev/index.d.mts +20 -0
- package/dist/dev/index.d.ts +20 -0
- package/dist/dev/index.js +51 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/index.mjs +49 -0
- package/dist/dev/index.mjs.map +1 -0
- package/dist/device/index.d.mts +108 -0
- package/dist/device/index.d.ts +108 -0
- package/dist/device/index.js +960 -0
- package/dist/device/index.js.map +1 -0
- package/dist/device/index.mjs +951 -0
- package/dist/device/index.mjs.map +1 -0
- package/dist/differential-privacy-BcAv1G80.d.mts +210 -0
- package/dist/differential-privacy-C8mAUjZr.d.ts +210 -0
- package/dist/encryption/index.d.mts +75 -0
- package/dist/encryption/index.d.ts +75 -0
- package/dist/encryption/index.js +605 -0
- package/dist/encryption/index.js.map +1 -0
- package/dist/encryption/index.mjs +598 -0
- package/dist/encryption/index.mjs.map +1 -0
- package/dist/form-validator-3tkmzr_o.d.mts +72 -0
- package/dist/form-validator-3tkmzr_o.d.ts +72 -0
- package/dist/forms/index.d.mts +59 -0
- package/dist/forms/index.d.ts +59 -0
- package/dist/forms/index.js +446 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/forms/index.mjs +442 -0
- package/dist/forms/index.mjs.map +1 -0
- package/dist/i18n/index.d.mts +37 -0
- package/dist/i18n/index.d.ts +37 -0
- package/dist/i18n/index.js +147 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/index.mjs +145 -0
- package/dist/i18n/index.mjs.map +1 -0
- package/dist/idempotency.service-_6LqhivP.d.mts +372 -0
- package/dist/idempotency.service-eOKoISRD.d.ts +372 -0
- package/dist/index-B_ksKpS1.d.mts +202 -0
- package/dist/index-CqDKWTUP.d.mts +28 -0
- package/dist/index-CqDKWTUP.d.ts +28 -0
- package/dist/index-DFqEoX_l.d.ts +202 -0
- package/dist/index-Dz0gOur2.d.mts +36 -0
- package/dist/index-Dz0gOur2.d.ts +36 -0
- package/dist/index.d.mts +1336 -0
- package/dist/index.d.ts +1336 -0
- package/dist/index.js +19464 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +19155 -0
- package/dist/index.mjs.map +1 -0
- package/dist/india/index.d.mts +75 -0
- package/dist/india/index.d.ts +75 -0
- package/dist/india/index.js +325 -0
- package/dist/india/index.js.map +1 -0
- package/dist/india/index.mjs +303 -0
- package/dist/india/index.mjs.map +1 -0
- package/dist/joop-Bx7Iwj5p.d.mts +155 -0
- package/dist/joop-CA3DMeOO.d.ts +155 -0
- package/dist/native-bridge/index.d.mts +27 -0
- package/dist/native-bridge/index.d.ts +27 -0
- package/dist/native-bridge/index.js +98 -0
- package/dist/native-bridge/index.js.map +1 -0
- package/dist/native-bridge/index.mjs +96 -0
- package/dist/native-bridge/index.mjs.map +1 -0
- package/dist/network/index.d.mts +85 -0
- package/dist/network/index.d.ts +85 -0
- package/dist/network/index.js +454 -0
- package/dist/network/index.js.map +1 -0
- package/dist/network/index.mjs +451 -0
- package/dist/network/index.mjs.map +1 -0
- package/dist/network-monitor-BIwPSXme.d.mts +179 -0
- package/dist/network-monitor-Bqp2hvZr.d.ts +179 -0
- package/dist/notification.service-Dm4fvfZf.d.mts +25 -0
- package/dist/notification.service-tEMKatWJ.d.ts +25 -0
- package/dist/observability/index.d.mts +179 -0
- package/dist/observability/index.d.ts +179 -0
- package/dist/observability/index.js +559 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/index.mjs +552 -0
- package/dist/observability/index.mjs.map +1 -0
- package/dist/oidc-client-DIJcClmB.d.mts +190 -0
- package/dist/oidc-client-DxhyE59t.d.ts +190 -0
- package/dist/platform/index.d.mts +73 -0
- package/dist/platform/index.d.ts +73 -0
- package/dist/platform/index.js +127 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/index.mjs +125 -0
- package/dist/platform/index.mjs.map +1 -0
- package/dist/pwa/index.d.mts +31 -0
- package/dist/pwa/index.d.ts +31 -0
- package/dist/pwa/index.js +247 -0
- package/dist/pwa/index.js.map +1 -0
- package/dist/pwa/index.mjs +244 -0
- package/dist/pwa/index.mjs.map +1 -0
- package/dist/react/index.d.mts +133 -0
- package/dist/react/index.d.ts +133 -0
- package/dist/react/index.js +632 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +630 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/router/index.d.mts +39 -0
- package/dist/router/index.d.ts +39 -0
- package/dist/router/index.js +168 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/index.mjs +166 -0
- package/dist/router/index.mjs.map +1 -0
- package/dist/security/index.d.mts +206 -0
- package/dist/security/index.d.ts +206 -0
- package/dist/security/index.js +1297 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/index.mjs +1285 -0
- package/dist/security/index.mjs.map +1 -0
- package/dist/session/index.d.mts +115 -0
- package/dist/session/index.d.ts +115 -0
- package/dist/session/index.js +297 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/index.mjs +292 -0
- package/dist/session/index.mjs.map +1 -0
- package/dist/state/index.d.mts +43 -0
- package/dist/state/index.d.ts +43 -0
- package/dist/state/index.js +156 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/index.mjs +152 -0
- package/dist/state/index.mjs.map +1 -0
- package/dist/statement-parser-BHQtXwCM.d.ts +260 -0
- package/dist/statement-parser-C2qNmb49.d.mts +260 -0
- package/dist/storage/index.d.mts +40 -0
- package/dist/storage/index.d.ts +40 -0
- package/dist/storage/index.js +256 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/index.mjs +252 -0
- package/dist/storage/index.mjs.map +1 -0
- package/dist/sync/index.d.mts +69 -0
- package/dist/sync/index.d.ts +69 -0
- package/dist/sync/index.js +330 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/index.mjs +323 -0
- package/dist/sync/index.mjs.map +1 -0
- package/dist/sync-engine-DCIMRG5s.d.ts +61 -0
- package/dist/sync-engine-DZqyKHkK.d.mts +61 -0
- package/dist/theme/index.d.mts +53 -0
- package/dist/theme/index.d.ts +53 -0
- package/dist/theme/index.js +169 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/index.mjs +167 -0
- package/dist/theme/index.mjs.map +1 -0
- package/dist/ui/index.d.mts +66 -0
- package/dist/ui/index.d.ts +66 -0
- package/dist/ui/index.js +811 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/index.mjs +803 -0
- package/dist/ui/index.mjs.map +1 -0
- package/dist/utilities/index.d.mts +199 -0
- package/dist/utilities/index.d.ts +199 -0
- package/dist/utilities/index.js +1991 -0
- package/dist/utilities/index.js.map +1 -0
- package/dist/utilities/index.mjs +1923 -0
- package/dist/utilities/index.mjs.map +1 -0
- package/dist/validation/index.d.mts +60 -0
- package/dist/validation/index.d.ts +60 -0
- package/dist/validation/index.js +460 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/index.mjs +455 -0
- package/dist/validation/index.mjs.map +1 -0
- package/dist/vue/index.d.mts +135 -0
- package/dist/vue/index.d.ts +135 -0
- package/dist/vue/index.js +621 -0
- package/dist/vue/index.js.map +1 -0
- package/dist/vue/index.mjs +619 -0
- package/dist/vue/index.mjs.map +1 -0
- package/dist/watermark.service-Detur5tq.d.ts +235 -0
- package/dist/watermark.service-QNegMeQZ.d.mts +235 -0
- package/dist/workers/index.d.mts +42 -0
- package/dist/workers/index.d.ts +42 -0
- package/dist/workers/index.js +359 -0
- package/dist/workers/index.js.map +1 -0
- package/dist/workers/index.mjs +356 -0
- package/dist/workers/index.mjs.map +1 -0
- package/dist/workflow/index.d.mts +99 -0
- package/dist/workflow/index.d.ts +99 -0
- package/dist/workflow/index.js +282 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/index.mjs +279 -0
- package/dist/workflow/index.mjs.map +1 -0
- package/package.json +226 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { J as JoopObservable } from '../index-Dz0gOur2.mjs';
|
|
2
|
+
|
|
3
|
+
type JoopReducer<S> = (state: S, payload: unknown) => S;
|
|
4
|
+
interface JoopStoreConfig<S> {
|
|
5
|
+
state: S;
|
|
6
|
+
reducers?: Record<string, JoopReducer<S>>;
|
|
7
|
+
maxHistory?: number;
|
|
8
|
+
}
|
|
9
|
+
interface JoopAction {
|
|
10
|
+
type: string;
|
|
11
|
+
payload?: unknown;
|
|
12
|
+
}
|
|
13
|
+
declare class JoopStore<S extends Record<string, unknown>> {
|
|
14
|
+
private _state$;
|
|
15
|
+
private _reducers;
|
|
16
|
+
private _history;
|
|
17
|
+
private _future;
|
|
18
|
+
private _maxHistory;
|
|
19
|
+
constructor(config: JoopStoreConfig<S>);
|
|
20
|
+
getState(): S;
|
|
21
|
+
dispatch(type: string, payload?: unknown): void;
|
|
22
|
+
/** Add a reducer after construction */
|
|
23
|
+
addReducer(type: string, reducer: JoopReducer<S>): void;
|
|
24
|
+
/** Observable of the entire state */
|
|
25
|
+
state$(): JoopObservable<S>;
|
|
26
|
+
/** Observable of a derived slice — only emits when the selected value changes */
|
|
27
|
+
select<T>(selector: (state: S) => T): JoopObservable<T>;
|
|
28
|
+
subscribe(handler: (state: S) => void): () => void;
|
|
29
|
+
undo(): void;
|
|
30
|
+
redo(): void;
|
|
31
|
+
canUndo(): boolean;
|
|
32
|
+
canRedo(): boolean;
|
|
33
|
+
reset(): void;
|
|
34
|
+
}
|
|
35
|
+
declare function createStore<S extends Record<string, unknown>>(config: JoopStoreConfig<S>): JoopStore<S>;
|
|
36
|
+
interface JoopSliceConfig<S, K extends keyof S> {
|
|
37
|
+
key: K;
|
|
38
|
+
reducers: Record<string, (slice: S[K], payload: unknown) => S[K]>;
|
|
39
|
+
}
|
|
40
|
+
/** Creates reducers scoped to a sub-key of the store state */
|
|
41
|
+
declare function createSlice<S extends Record<string, unknown>, K extends keyof S>(cfg: JoopSliceConfig<S, K>): Record<string, JoopReducer<S>>;
|
|
42
|
+
|
|
43
|
+
export { type JoopAction, type JoopReducer, type JoopSliceConfig, JoopStore, type JoopStoreConfig, createSlice, createStore };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { J as JoopObservable } from '../index-Dz0gOur2.js';
|
|
2
|
+
|
|
3
|
+
type JoopReducer<S> = (state: S, payload: unknown) => S;
|
|
4
|
+
interface JoopStoreConfig<S> {
|
|
5
|
+
state: S;
|
|
6
|
+
reducers?: Record<string, JoopReducer<S>>;
|
|
7
|
+
maxHistory?: number;
|
|
8
|
+
}
|
|
9
|
+
interface JoopAction {
|
|
10
|
+
type: string;
|
|
11
|
+
payload?: unknown;
|
|
12
|
+
}
|
|
13
|
+
declare class JoopStore<S extends Record<string, unknown>> {
|
|
14
|
+
private _state$;
|
|
15
|
+
private _reducers;
|
|
16
|
+
private _history;
|
|
17
|
+
private _future;
|
|
18
|
+
private _maxHistory;
|
|
19
|
+
constructor(config: JoopStoreConfig<S>);
|
|
20
|
+
getState(): S;
|
|
21
|
+
dispatch(type: string, payload?: unknown): void;
|
|
22
|
+
/** Add a reducer after construction */
|
|
23
|
+
addReducer(type: string, reducer: JoopReducer<S>): void;
|
|
24
|
+
/** Observable of the entire state */
|
|
25
|
+
state$(): JoopObservable<S>;
|
|
26
|
+
/** Observable of a derived slice — only emits when the selected value changes */
|
|
27
|
+
select<T>(selector: (state: S) => T): JoopObservable<T>;
|
|
28
|
+
subscribe(handler: (state: S) => void): () => void;
|
|
29
|
+
undo(): void;
|
|
30
|
+
redo(): void;
|
|
31
|
+
canUndo(): boolean;
|
|
32
|
+
canRedo(): boolean;
|
|
33
|
+
reset(): void;
|
|
34
|
+
}
|
|
35
|
+
declare function createStore<S extends Record<string, unknown>>(config: JoopStoreConfig<S>): JoopStore<S>;
|
|
36
|
+
interface JoopSliceConfig<S, K extends keyof S> {
|
|
37
|
+
key: K;
|
|
38
|
+
reducers: Record<string, (slice: S[K], payload: unknown) => S[K]>;
|
|
39
|
+
}
|
|
40
|
+
/** Creates reducers scoped to a sub-key of the store state */
|
|
41
|
+
declare function createSlice<S extends Record<string, unknown>, K extends keyof S>(cfg: JoopSliceConfig<S, K>): Record<string, JoopReducer<S>>;
|
|
42
|
+
|
|
43
|
+
export { type JoopAction, type JoopReducer, type JoopSliceConfig, JoopStore, type JoopStoreConfig, createSlice, createStore };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/events/index.ts
|
|
4
|
+
var JoopSubject = class {
|
|
5
|
+
_listeners = [];
|
|
6
|
+
subscribe(listener) {
|
|
7
|
+
this._listeners.push(listener);
|
|
8
|
+
return () => {
|
|
9
|
+
this._listeners = this._listeners.filter((l) => l !== listener);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
next(value) {
|
|
13
|
+
for (const listener of this._listeners) {
|
|
14
|
+
listener(value);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
asObservable() {
|
|
18
|
+
return new JoopObservable((listener) => this.subscribe(listener));
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var JoopBehaviorSubject = class extends JoopSubject {
|
|
22
|
+
_value;
|
|
23
|
+
constructor(initialValue) {
|
|
24
|
+
super();
|
|
25
|
+
this._value = initialValue;
|
|
26
|
+
}
|
|
27
|
+
getValue() {
|
|
28
|
+
return this._value;
|
|
29
|
+
}
|
|
30
|
+
next(value) {
|
|
31
|
+
this._value = value;
|
|
32
|
+
super.next(value);
|
|
33
|
+
}
|
|
34
|
+
subscribe(listener) {
|
|
35
|
+
listener(this._value);
|
|
36
|
+
return super.subscribe(listener);
|
|
37
|
+
}
|
|
38
|
+
asObservable() {
|
|
39
|
+
return new JoopObservable((listener) => this.subscribe(listener));
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var JoopObservable = class {
|
|
43
|
+
constructor(_subscribeFn) {
|
|
44
|
+
this._subscribeFn = _subscribeFn;
|
|
45
|
+
}
|
|
46
|
+
_subscribeFn;
|
|
47
|
+
subscribe(listener) {
|
|
48
|
+
return this._subscribeFn(listener);
|
|
49
|
+
}
|
|
50
|
+
/** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */
|
|
51
|
+
getOnce() {
|
|
52
|
+
let result;
|
|
53
|
+
const unsub = this.subscribe((v) => {
|
|
54
|
+
result = v;
|
|
55
|
+
});
|
|
56
|
+
unsub();
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// src/state/observable-store.ts
|
|
62
|
+
var JoopStore = class {
|
|
63
|
+
_state$;
|
|
64
|
+
_reducers;
|
|
65
|
+
_history;
|
|
66
|
+
_future = [];
|
|
67
|
+
_maxHistory;
|
|
68
|
+
constructor(config) {
|
|
69
|
+
this._state$ = new JoopBehaviorSubject(config.state);
|
|
70
|
+
this._reducers = config.reducers ?? {};
|
|
71
|
+
this._maxHistory = config.maxHistory ?? 50;
|
|
72
|
+
this._history = [config.state];
|
|
73
|
+
}
|
|
74
|
+
getState() {
|
|
75
|
+
return this._state$.getValue();
|
|
76
|
+
}
|
|
77
|
+
dispatch(type, payload) {
|
|
78
|
+
const reducer = this._reducers[type];
|
|
79
|
+
if (!reducer) throw new Error(`JoopStore: no reducer for action '${type}'`);
|
|
80
|
+
const current = this._state$.getValue();
|
|
81
|
+
const next = reducer(current, payload);
|
|
82
|
+
if (next === current) return;
|
|
83
|
+
this._history.push(current);
|
|
84
|
+
if (this._history.length > this._maxHistory) this._history.shift();
|
|
85
|
+
this._future = [];
|
|
86
|
+
this._state$.next(next);
|
|
87
|
+
}
|
|
88
|
+
/** Add a reducer after construction */
|
|
89
|
+
addReducer(type, reducer) {
|
|
90
|
+
this._reducers[type] = reducer;
|
|
91
|
+
}
|
|
92
|
+
/** Observable of the entire state */
|
|
93
|
+
state$() {
|
|
94
|
+
return this._state$.asObservable();
|
|
95
|
+
}
|
|
96
|
+
/** Observable of a derived slice — only emits when the selected value changes */
|
|
97
|
+
select(selector) {
|
|
98
|
+
let lastValue = _UNSET;
|
|
99
|
+
const subject = new JoopBehaviorSubject(selector(this.getState()));
|
|
100
|
+
this._state$.subscribe((s) => {
|
|
101
|
+
const v = selector(s);
|
|
102
|
+
if (v !== lastValue) {
|
|
103
|
+
lastValue = v;
|
|
104
|
+
subject.next(v);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return subject.asObservable();
|
|
108
|
+
}
|
|
109
|
+
subscribe(handler) {
|
|
110
|
+
return this._state$.subscribe(handler);
|
|
111
|
+
}
|
|
112
|
+
undo() {
|
|
113
|
+
if (!this.canUndo()) return;
|
|
114
|
+
const prev = this._history.pop();
|
|
115
|
+
this._future.push(this._state$.getValue());
|
|
116
|
+
this._state$.next(prev);
|
|
117
|
+
}
|
|
118
|
+
redo() {
|
|
119
|
+
if (!this.canRedo()) return;
|
|
120
|
+
const next = this._future.pop();
|
|
121
|
+
this._history.push(this._state$.getValue());
|
|
122
|
+
this._state$.next(next);
|
|
123
|
+
}
|
|
124
|
+
canUndo() {
|
|
125
|
+
return this._history.length > 1;
|
|
126
|
+
}
|
|
127
|
+
canRedo() {
|
|
128
|
+
return this._future.length > 0;
|
|
129
|
+
}
|
|
130
|
+
reset() {
|
|
131
|
+
const initial = this._history[0];
|
|
132
|
+
this._history = [initial];
|
|
133
|
+
this._future = [];
|
|
134
|
+
this._state$.next(initial);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var _UNSET = /* @__PURE__ */ Symbol("unset");
|
|
138
|
+
function createStore(config) {
|
|
139
|
+
return new JoopStore(config);
|
|
140
|
+
}
|
|
141
|
+
function createSlice(cfg) {
|
|
142
|
+
const out = {};
|
|
143
|
+
for (const [type, reducer] of Object.entries(cfg.reducers)) {
|
|
144
|
+
out[`${String(cfg.key)}/${type}`] = (state, payload) => ({
|
|
145
|
+
...state,
|
|
146
|
+
[cfg.key]: reducer(state[cfg.key], payload)
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
exports.JoopStore = JoopStore;
|
|
153
|
+
exports.createSlice = createSlice;
|
|
154
|
+
exports.createStore = createStore;
|
|
155
|
+
//# sourceMappingURL=index.js.map
|
|
156
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/events/index.ts","../../src/state/observable-store.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject } from '../events';\n\nexport type JoopReducer<S> = (state: S, payload: unknown) => S;\n\nexport interface JoopStoreConfig<S> {\n state: S;\n reducers?: Record<string, JoopReducer<S>>;\n maxHistory?: number;\n}\n\nexport interface JoopAction {\n type: string;\n payload?: unknown;\n}\n\nexport class JoopStore<S extends Record<string, unknown>> {\n private _state$: JoopBehaviorSubject<S>;\n private _reducers: Record<string, JoopReducer<S>>;\n private _history: S[];\n private _future: S[] = [];\n private _maxHistory: number;\n\n constructor(config: JoopStoreConfig<S>) {\n this._state$ = new JoopBehaviorSubject<S>(config.state);\n this._reducers = config.reducers ?? {};\n this._maxHistory = config.maxHistory ?? 50;\n this._history = [config.state];\n }\n\n getState(): S { return this._state$.getValue(); }\n\n dispatch(type: string, payload?: unknown): void {\n const reducer = this._reducers[type];\n if (!reducer) throw new Error(`JoopStore: no reducer for action '${type}'`);\n\n const current = this._state$.getValue();\n const next = reducer(current, payload);\n if (next === current) return;\n\n this._history.push(current);\n if (this._history.length > this._maxHistory) this._history.shift();\n this._future = [];\n this._state$.next(next);\n }\n\n /** Add a reducer after construction */\n addReducer(type: string, reducer: JoopReducer<S>): void { this._reducers[type] = reducer; }\n\n /** Observable of the entire state */\n state$() { return this._state$.asObservable(); }\n\n /** Observable of a derived slice — only emits when the selected value changes */\n select<T>(selector: (state: S) => T) {\n let lastValue: T | typeof _UNSET = _UNSET;\n const subject = new JoopBehaviorSubject<T>(selector(this.getState()));\n this._state$.subscribe(s => {\n const v = selector(s);\n if (v !== lastValue) { lastValue = v; subject.next(v); }\n });\n return subject.asObservable();\n }\n\n subscribe(handler: (state: S) => void): () => void {\n return this._state$.subscribe(handler);\n }\n\n undo(): void {\n if (!this.canUndo()) return;\n const prev = this._history.pop()!;\n this._future.push(this._state$.getValue());\n this._state$.next(prev);\n }\n\n redo(): void {\n if (!this.canRedo()) return;\n const next = this._future.pop()!;\n this._history.push(this._state$.getValue());\n this._state$.next(next);\n }\n\n canUndo(): boolean { return this._history.length > 1; }\n canRedo(): boolean { return this._future.length > 0; }\n\n reset(): void {\n const initial = this._history[0];\n this._history = [initial];\n this._future = [];\n this._state$.next(initial);\n }\n}\n\nconst _UNSET = Symbol('unset');\n\nexport function createStore<S extends Record<string, unknown>>(config: JoopStoreConfig<S>): JoopStore<S> {\n return new JoopStore(config);\n}\n\n// ─── Slice helper ───────────────────────────────────────────────────────────\n\nexport interface JoopSliceConfig<S, K extends keyof S> {\n key: K;\n reducers: Record<string, (slice: S[K], payload: unknown) => S[K]>;\n}\n\n/** Creates reducers scoped to a sub-key of the store state */\nexport function createSlice<S extends Record<string, unknown>, K extends keyof S>(\n cfg: JoopSliceConfig<S, K>\n): Record<string, JoopReducer<S>> {\n const out: Record<string, JoopReducer<S>> = {};\n for (const [type, reducer] of Object.entries(cfg.reducers)) {\n out[`${String(cfg.key)}/${type}`] = (state, payload) => ({\n ...state,\n [cfg.key]: reducer(state[cfg.key] as S[K], payload),\n });\n }\n return out;\n}\n"]}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// src/events/index.ts
|
|
2
|
+
var JoopSubject = class {
|
|
3
|
+
_listeners = [];
|
|
4
|
+
subscribe(listener) {
|
|
5
|
+
this._listeners.push(listener);
|
|
6
|
+
return () => {
|
|
7
|
+
this._listeners = this._listeners.filter((l) => l !== listener);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
next(value) {
|
|
11
|
+
for (const listener of this._listeners) {
|
|
12
|
+
listener(value);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
asObservable() {
|
|
16
|
+
return new JoopObservable((listener) => this.subscribe(listener));
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var JoopBehaviorSubject = class extends JoopSubject {
|
|
20
|
+
_value;
|
|
21
|
+
constructor(initialValue) {
|
|
22
|
+
super();
|
|
23
|
+
this._value = initialValue;
|
|
24
|
+
}
|
|
25
|
+
getValue() {
|
|
26
|
+
return this._value;
|
|
27
|
+
}
|
|
28
|
+
next(value) {
|
|
29
|
+
this._value = value;
|
|
30
|
+
super.next(value);
|
|
31
|
+
}
|
|
32
|
+
subscribe(listener) {
|
|
33
|
+
listener(this._value);
|
|
34
|
+
return super.subscribe(listener);
|
|
35
|
+
}
|
|
36
|
+
asObservable() {
|
|
37
|
+
return new JoopObservable((listener) => this.subscribe(listener));
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var JoopObservable = class {
|
|
41
|
+
constructor(_subscribeFn) {
|
|
42
|
+
this._subscribeFn = _subscribeFn;
|
|
43
|
+
}
|
|
44
|
+
_subscribeFn;
|
|
45
|
+
subscribe(listener) {
|
|
46
|
+
return this._subscribeFn(listener);
|
|
47
|
+
}
|
|
48
|
+
/** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */
|
|
49
|
+
getOnce() {
|
|
50
|
+
let result;
|
|
51
|
+
const unsub = this.subscribe((v) => {
|
|
52
|
+
result = v;
|
|
53
|
+
});
|
|
54
|
+
unsub();
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// src/state/observable-store.ts
|
|
60
|
+
var JoopStore = class {
|
|
61
|
+
_state$;
|
|
62
|
+
_reducers;
|
|
63
|
+
_history;
|
|
64
|
+
_future = [];
|
|
65
|
+
_maxHistory;
|
|
66
|
+
constructor(config) {
|
|
67
|
+
this._state$ = new JoopBehaviorSubject(config.state);
|
|
68
|
+
this._reducers = config.reducers ?? {};
|
|
69
|
+
this._maxHistory = config.maxHistory ?? 50;
|
|
70
|
+
this._history = [config.state];
|
|
71
|
+
}
|
|
72
|
+
getState() {
|
|
73
|
+
return this._state$.getValue();
|
|
74
|
+
}
|
|
75
|
+
dispatch(type, payload) {
|
|
76
|
+
const reducer = this._reducers[type];
|
|
77
|
+
if (!reducer) throw new Error(`JoopStore: no reducer for action '${type}'`);
|
|
78
|
+
const current = this._state$.getValue();
|
|
79
|
+
const next = reducer(current, payload);
|
|
80
|
+
if (next === current) return;
|
|
81
|
+
this._history.push(current);
|
|
82
|
+
if (this._history.length > this._maxHistory) this._history.shift();
|
|
83
|
+
this._future = [];
|
|
84
|
+
this._state$.next(next);
|
|
85
|
+
}
|
|
86
|
+
/** Add a reducer after construction */
|
|
87
|
+
addReducer(type, reducer) {
|
|
88
|
+
this._reducers[type] = reducer;
|
|
89
|
+
}
|
|
90
|
+
/** Observable of the entire state */
|
|
91
|
+
state$() {
|
|
92
|
+
return this._state$.asObservable();
|
|
93
|
+
}
|
|
94
|
+
/** Observable of a derived slice — only emits when the selected value changes */
|
|
95
|
+
select(selector) {
|
|
96
|
+
let lastValue = _UNSET;
|
|
97
|
+
const subject = new JoopBehaviorSubject(selector(this.getState()));
|
|
98
|
+
this._state$.subscribe((s) => {
|
|
99
|
+
const v = selector(s);
|
|
100
|
+
if (v !== lastValue) {
|
|
101
|
+
lastValue = v;
|
|
102
|
+
subject.next(v);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
return subject.asObservable();
|
|
106
|
+
}
|
|
107
|
+
subscribe(handler) {
|
|
108
|
+
return this._state$.subscribe(handler);
|
|
109
|
+
}
|
|
110
|
+
undo() {
|
|
111
|
+
if (!this.canUndo()) return;
|
|
112
|
+
const prev = this._history.pop();
|
|
113
|
+
this._future.push(this._state$.getValue());
|
|
114
|
+
this._state$.next(prev);
|
|
115
|
+
}
|
|
116
|
+
redo() {
|
|
117
|
+
if (!this.canRedo()) return;
|
|
118
|
+
const next = this._future.pop();
|
|
119
|
+
this._history.push(this._state$.getValue());
|
|
120
|
+
this._state$.next(next);
|
|
121
|
+
}
|
|
122
|
+
canUndo() {
|
|
123
|
+
return this._history.length > 1;
|
|
124
|
+
}
|
|
125
|
+
canRedo() {
|
|
126
|
+
return this._future.length > 0;
|
|
127
|
+
}
|
|
128
|
+
reset() {
|
|
129
|
+
const initial = this._history[0];
|
|
130
|
+
this._history = [initial];
|
|
131
|
+
this._future = [];
|
|
132
|
+
this._state$.next(initial);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
var _UNSET = /* @__PURE__ */ Symbol("unset");
|
|
136
|
+
function createStore(config) {
|
|
137
|
+
return new JoopStore(config);
|
|
138
|
+
}
|
|
139
|
+
function createSlice(cfg) {
|
|
140
|
+
const out = {};
|
|
141
|
+
for (const [type, reducer] of Object.entries(cfg.reducers)) {
|
|
142
|
+
out[`${String(cfg.key)}/${type}`] = (state, payload) => ({
|
|
143
|
+
...state,
|
|
144
|
+
[cfg.key]: reducer(state[cfg.key], payload)
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { JoopStore, createSlice, createStore };
|
|
151
|
+
//# sourceMappingURL=index.mjs.map
|
|
152
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/events/index.ts","../../src/state/observable-store.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject } from '../events';\n\nexport type JoopReducer<S> = (state: S, payload: unknown) => S;\n\nexport interface JoopStoreConfig<S> {\n state: S;\n reducers?: Record<string, JoopReducer<S>>;\n maxHistory?: number;\n}\n\nexport interface JoopAction {\n type: string;\n payload?: unknown;\n}\n\nexport class JoopStore<S extends Record<string, unknown>> {\n private _state$: JoopBehaviorSubject<S>;\n private _reducers: Record<string, JoopReducer<S>>;\n private _history: S[];\n private _future: S[] = [];\n private _maxHistory: number;\n\n constructor(config: JoopStoreConfig<S>) {\n this._state$ = new JoopBehaviorSubject<S>(config.state);\n this._reducers = config.reducers ?? {};\n this._maxHistory = config.maxHistory ?? 50;\n this._history = [config.state];\n }\n\n getState(): S { return this._state$.getValue(); }\n\n dispatch(type: string, payload?: unknown): void {\n const reducer = this._reducers[type];\n if (!reducer) throw new Error(`JoopStore: no reducer for action '${type}'`);\n\n const current = this._state$.getValue();\n const next = reducer(current, payload);\n if (next === current) return;\n\n this._history.push(current);\n if (this._history.length > this._maxHistory) this._history.shift();\n this._future = [];\n this._state$.next(next);\n }\n\n /** Add a reducer after construction */\n addReducer(type: string, reducer: JoopReducer<S>): void { this._reducers[type] = reducer; }\n\n /** Observable of the entire state */\n state$() { return this._state$.asObservable(); }\n\n /** Observable of a derived slice — only emits when the selected value changes */\n select<T>(selector: (state: S) => T) {\n let lastValue: T | typeof _UNSET = _UNSET;\n const subject = new JoopBehaviorSubject<T>(selector(this.getState()));\n this._state$.subscribe(s => {\n const v = selector(s);\n if (v !== lastValue) { lastValue = v; subject.next(v); }\n });\n return subject.asObservable();\n }\n\n subscribe(handler: (state: S) => void): () => void {\n return this._state$.subscribe(handler);\n }\n\n undo(): void {\n if (!this.canUndo()) return;\n const prev = this._history.pop()!;\n this._future.push(this._state$.getValue());\n this._state$.next(prev);\n }\n\n redo(): void {\n if (!this.canRedo()) return;\n const next = this._future.pop()!;\n this._history.push(this._state$.getValue());\n this._state$.next(next);\n }\n\n canUndo(): boolean { return this._history.length > 1; }\n canRedo(): boolean { return this._future.length > 0; }\n\n reset(): void {\n const initial = this._history[0];\n this._history = [initial];\n this._future = [];\n this._state$.next(initial);\n }\n}\n\nconst _UNSET = Symbol('unset');\n\nexport function createStore<S extends Record<string, unknown>>(config: JoopStoreConfig<S>): JoopStore<S> {\n return new JoopStore(config);\n}\n\n// ─── Slice helper ───────────────────────────────────────────────────────────\n\nexport interface JoopSliceConfig<S, K extends keyof S> {\n key: K;\n reducers: Record<string, (slice: S[K], payload: unknown) => S[K]>;\n}\n\n/** Creates reducers scoped to a sub-key of the store state */\nexport function createSlice<S extends Record<string, unknown>, K extends keyof S>(\n cfg: JoopSliceConfig<S, K>\n): Record<string, JoopReducer<S>> {\n const out: Record<string, JoopReducer<S>> = {};\n for (const [type, reducer] of Object.entries(cfg.reducers)) {\n out[`${String(cfg.key)}/${type}`] = (state, payload) => ({\n ...state,\n [cfg.key]: reducer(state[cfg.key] as S[K], payload),\n });\n }\n return out;\n}\n"]}
|