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,323 @@
|
|
|
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/sync/sync-engine.ts
|
|
60
|
+
var JoopSyncEngine = class {
|
|
61
|
+
_cfg = null;
|
|
62
|
+
_mutations = [];
|
|
63
|
+
_conflicts = [];
|
|
64
|
+
_syncing = false;
|
|
65
|
+
_syncedCount = 0;
|
|
66
|
+
_lastSyncAt = null;
|
|
67
|
+
_online = typeof navigator !== "undefined" ? navigator.onLine : true;
|
|
68
|
+
_status$ = new JoopBehaviorSubject(this._buildStatus());
|
|
69
|
+
_conflict$ = new JoopSubject();
|
|
70
|
+
_onlineHandlers = [];
|
|
71
|
+
configure(config) {
|
|
72
|
+
this._cfg = config;
|
|
73
|
+
if (typeof window !== "undefined") {
|
|
74
|
+
const onOnline = () => {
|
|
75
|
+
this._online = true;
|
|
76
|
+
this._updateStatus();
|
|
77
|
+
this.sync();
|
|
78
|
+
};
|
|
79
|
+
const onOffline = () => {
|
|
80
|
+
this._online = false;
|
|
81
|
+
this._updateStatus();
|
|
82
|
+
};
|
|
83
|
+
window.addEventListener("online", onOnline);
|
|
84
|
+
window.addEventListener("offline", onOffline);
|
|
85
|
+
this._onlineHandlers.push(
|
|
86
|
+
() => window.removeEventListener("online", onOnline),
|
|
87
|
+
() => window.removeEventListener("offline", onOffline)
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
destroy() {
|
|
92
|
+
for (const rm of this._onlineHandlers) rm();
|
|
93
|
+
this._onlineHandlers = [];
|
|
94
|
+
}
|
|
95
|
+
mutate(type, payload) {
|
|
96
|
+
const m = { id: _uid(), type, payload, status: "pending", timestamp: Date.now(), retries: 0 };
|
|
97
|
+
this._mutations.push(m);
|
|
98
|
+
this._updateStatus();
|
|
99
|
+
if (this._online && !this._syncing) this.sync();
|
|
100
|
+
return m;
|
|
101
|
+
}
|
|
102
|
+
pending() {
|
|
103
|
+
return this._mutations.filter((m) => m.status === "pending" || m.status === "failed");
|
|
104
|
+
}
|
|
105
|
+
conflicts() {
|
|
106
|
+
return [...this._conflicts];
|
|
107
|
+
}
|
|
108
|
+
status$() {
|
|
109
|
+
return this._status$.asObservable();
|
|
110
|
+
}
|
|
111
|
+
conflict$() {
|
|
112
|
+
return this._conflict$.asObservable();
|
|
113
|
+
}
|
|
114
|
+
async sync() {
|
|
115
|
+
if (!this._cfg || this._syncing || !this._online) return;
|
|
116
|
+
const pending = this.pending();
|
|
117
|
+
if (pending.length === 0) return;
|
|
118
|
+
this._syncing = true;
|
|
119
|
+
this._updateStatus();
|
|
120
|
+
const { syncUrl, headers = {}, maxRetries = 3, batchSize = 50 } = this._cfg;
|
|
121
|
+
const batch = pending.slice(0, batchSize);
|
|
122
|
+
try {
|
|
123
|
+
for (const m of batch) m.status = "syncing";
|
|
124
|
+
const res = await fetch(syncUrl, {
|
|
125
|
+
method: "POST",
|
|
126
|
+
headers: { "Content-Type": "application/json", ...headers },
|
|
127
|
+
body: JSON.stringify({ mutations: batch.map((m) => ({ id: m.id, type: m.type, payload: m.payload, timestamp: m.timestamp })) })
|
|
128
|
+
});
|
|
129
|
+
if (!res.ok) throw new Error(`Sync failed: ${res.status}`);
|
|
130
|
+
const data = await res.json();
|
|
131
|
+
for (const result of data.results ?? []) {
|
|
132
|
+
const m = this._mutations.find((x) => x.id === result.id);
|
|
133
|
+
if (!m) continue;
|
|
134
|
+
if (result.status === "ok") {
|
|
135
|
+
m.status = "synced";
|
|
136
|
+
this._syncedCount++;
|
|
137
|
+
} else if (result.status === "conflict") {
|
|
138
|
+
m.status = "failed";
|
|
139
|
+
const conflict = { id: _uid(), mutationId: m.id, local: m.payload, remote: result.remote };
|
|
140
|
+
this._conflicts.push(conflict);
|
|
141
|
+
this._conflict$.next(conflict);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} catch {
|
|
145
|
+
for (const m of batch) {
|
|
146
|
+
m.retries++;
|
|
147
|
+
m.status = m.retries >= maxRetries ? "failed" : "pending";
|
|
148
|
+
}
|
|
149
|
+
} finally {
|
|
150
|
+
this._syncing = false;
|
|
151
|
+
this._lastSyncAt = Date.now();
|
|
152
|
+
this._updateStatus();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
resolve(conflictId, strategy, mergeFn) {
|
|
156
|
+
const conflict = this._conflicts.find((c) => c.id === conflictId);
|
|
157
|
+
if (!conflict) return;
|
|
158
|
+
const m = this._mutations.find((x) => x.id === conflict.mutationId);
|
|
159
|
+
if (m) {
|
|
160
|
+
if (strategy === "remote") m.payload = conflict.remote;
|
|
161
|
+
else if (strategy === "merge" && mergeFn) m.payload = mergeFn(conflict.local, conflict.remote);
|
|
162
|
+
m.status = "pending";
|
|
163
|
+
m.retries = 0;
|
|
164
|
+
}
|
|
165
|
+
conflict.resolvedAt = Date.now();
|
|
166
|
+
conflict.resolution = strategy === "merge" ? "merged" : strategy;
|
|
167
|
+
this._conflicts = this._conflicts.filter((c) => c.id !== conflictId);
|
|
168
|
+
if (this._online) this.sync();
|
|
169
|
+
}
|
|
170
|
+
clearSynced() {
|
|
171
|
+
this._mutations = this._mutations.filter((m) => m.status !== "synced");
|
|
172
|
+
this._updateStatus();
|
|
173
|
+
}
|
|
174
|
+
_buildStatus() {
|
|
175
|
+
return {
|
|
176
|
+
online: this._online,
|
|
177
|
+
pendingCount: this._mutations.filter((m) => m.status === "pending").length,
|
|
178
|
+
syncedCount: this._syncedCount,
|
|
179
|
+
failedCount: this._mutations.filter((m) => m.status === "failed").length,
|
|
180
|
+
lastSyncAt: this._lastSyncAt,
|
|
181
|
+
syncing: this._syncing
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
_updateStatus() {
|
|
185
|
+
this._status$.next(this._buildStatus());
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
function _uid() {
|
|
189
|
+
return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/sync/crdt.ts
|
|
193
|
+
var CRDTCounter = class _CRDTCounter {
|
|
194
|
+
_inc = {};
|
|
195
|
+
_dec = {};
|
|
196
|
+
increment(nodeId, by = 1) {
|
|
197
|
+
this._inc[nodeId] = (this._inc[nodeId] ?? 0) + by;
|
|
198
|
+
}
|
|
199
|
+
decrement(nodeId, by = 1) {
|
|
200
|
+
this._dec[nodeId] = (this._dec[nodeId] ?? 0) + by;
|
|
201
|
+
}
|
|
202
|
+
value() {
|
|
203
|
+
const inc = Object.values(this._inc).reduce((s, v) => s + v, 0);
|
|
204
|
+
const dec = Object.values(this._dec).reduce((s, v) => s + v, 0);
|
|
205
|
+
return inc - dec;
|
|
206
|
+
}
|
|
207
|
+
merge(remote) {
|
|
208
|
+
for (const [id, v] of Object.entries(remote._inc)) this._inc[id] = Math.max(this._inc[id] ?? 0, v);
|
|
209
|
+
for (const [id, v] of Object.entries(remote._dec)) this._dec[id] = Math.max(this._dec[id] ?? 0, v);
|
|
210
|
+
}
|
|
211
|
+
state() {
|
|
212
|
+
return { inc: { ...this._inc }, dec: { ...this._dec } };
|
|
213
|
+
}
|
|
214
|
+
static fromState(s) {
|
|
215
|
+
const c = new _CRDTCounter();
|
|
216
|
+
c._inc = { ...s.inc };
|
|
217
|
+
c._dec = { ...s.dec };
|
|
218
|
+
return c;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
var CRDTSet = class {
|
|
222
|
+
_added = /* @__PURE__ */ new Map();
|
|
223
|
+
_removed = /* @__PURE__ */ new Set();
|
|
224
|
+
add(uniqueId, item) {
|
|
225
|
+
this._added.set(uniqueId, item);
|
|
226
|
+
this._removed.delete(uniqueId);
|
|
227
|
+
}
|
|
228
|
+
remove(uniqueId) {
|
|
229
|
+
this._removed.add(uniqueId);
|
|
230
|
+
}
|
|
231
|
+
has(uniqueId) {
|
|
232
|
+
return this._added.has(uniqueId) && !this._removed.has(uniqueId);
|
|
233
|
+
}
|
|
234
|
+
values() {
|
|
235
|
+
return Array.from(this._added.entries()).filter(([id]) => !this._removed.has(id)).map(([, v]) => v);
|
|
236
|
+
}
|
|
237
|
+
size() {
|
|
238
|
+
return this.values().length;
|
|
239
|
+
}
|
|
240
|
+
merge(remote) {
|
|
241
|
+
for (const [id, item] of remote._added) if (!this._added.has(id)) this._added.set(id, item);
|
|
242
|
+
for (const id of remote._removed) this._removed.add(id);
|
|
243
|
+
}
|
|
244
|
+
state() {
|
|
245
|
+
return { added: Array.from(this._added.entries()), removed: Array.from(this._removed) };
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
var CRDTRegister = class {
|
|
249
|
+
_value;
|
|
250
|
+
_timestamp;
|
|
251
|
+
_nodeId;
|
|
252
|
+
constructor(initial, nodeId = "default", timestamp = 0) {
|
|
253
|
+
this._value = initial;
|
|
254
|
+
this._timestamp = timestamp;
|
|
255
|
+
this._nodeId = nodeId;
|
|
256
|
+
}
|
|
257
|
+
set(value, nodeId, timestamp) {
|
|
258
|
+
const ts = timestamp ?? Date.now();
|
|
259
|
+
if (ts > this._timestamp || ts === this._timestamp && nodeId > this._nodeId) {
|
|
260
|
+
this._value = value;
|
|
261
|
+
this._timestamp = ts;
|
|
262
|
+
this._nodeId = nodeId;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
get() {
|
|
266
|
+
return this._value;
|
|
267
|
+
}
|
|
268
|
+
timestamp() {
|
|
269
|
+
return this._timestamp;
|
|
270
|
+
}
|
|
271
|
+
merge(remote) {
|
|
272
|
+
this.set(remote._value, remote._nodeId, remote._timestamp);
|
|
273
|
+
}
|
|
274
|
+
state() {
|
|
275
|
+
return { value: this._value, timestamp: this._timestamp, nodeId: this._nodeId };
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var CRDTText = class {
|
|
279
|
+
_chars = [];
|
|
280
|
+
_index = /* @__PURE__ */ new Map();
|
|
281
|
+
insert(after, char, nodeId, seq) {
|
|
282
|
+
const id = `${nodeId}:${seq}`;
|
|
283
|
+
const c = { id, char, after, deleted: false };
|
|
284
|
+
const pos = after === null ? 0 : this._chars.findIndex((ch) => ch.id === after) + 1;
|
|
285
|
+
this._chars.splice(pos, 0, c);
|
|
286
|
+
this._index.set(id, c);
|
|
287
|
+
return id;
|
|
288
|
+
}
|
|
289
|
+
delete(id) {
|
|
290
|
+
const c = this._index.get(id);
|
|
291
|
+
if (c) c.deleted = true;
|
|
292
|
+
}
|
|
293
|
+
toString() {
|
|
294
|
+
return this._chars.filter((c) => !c.deleted).map((c) => c.char).join("");
|
|
295
|
+
}
|
|
296
|
+
length() {
|
|
297
|
+
return this._chars.filter((c) => !c.deleted).length;
|
|
298
|
+
}
|
|
299
|
+
merge(remote) {
|
|
300
|
+
for (const rc of remote._chars) {
|
|
301
|
+
if (!this._index.has(rc.id)) {
|
|
302
|
+
const c = { ...rc };
|
|
303
|
+
const pos = rc.after === null ? 0 : this._chars.findIndex((ch) => ch.id === rc.after) + 1;
|
|
304
|
+
this._chars.splice(pos, 0, c);
|
|
305
|
+
this._index.set(c.id, c);
|
|
306
|
+
} else if (rc.deleted) {
|
|
307
|
+
const existing = this._index.get(rc.id);
|
|
308
|
+
existing.deleted = true;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
state() {
|
|
313
|
+
return this._chars.map((c) => ({ ...c }));
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
function mergeCRDT(local, remote) {
|
|
317
|
+
local.merge(remote);
|
|
318
|
+
return local;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export { CRDTCounter, CRDTRegister, CRDTSet, CRDTText, JoopSyncEngine, mergeCRDT };
|
|
322
|
+
//# sourceMappingURL=index.mjs.map
|
|
323
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/events/index.ts","../../src/sync/sync-engine.ts","../../src/sync/crdt.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, JoopSubject } from '../events';\n\nexport type JoopSyncConflictStrategy = 'local-wins' | 'remote-wins' | 'merge';\n\nexport interface JoopSyncConfig {\n syncUrl: string;\n headers?: Record<string, string>;\n retryMs?: number;\n maxRetries?: number;\n conflictStrategy?: JoopSyncConflictStrategy;\n batchSize?: number;\n}\n\nexport interface JoopMutation {\n id: string;\n type: string;\n payload: unknown;\n status: 'pending' | 'syncing' | 'synced' | 'failed';\n timestamp: number;\n retries: number;\n}\n\nexport interface JoopSyncConflict {\n id: string;\n mutationId: string;\n local: unknown;\n remote: unknown;\n resolvedAt?: number;\n resolution?: 'local' | 'remote' | 'merged';\n}\n\nexport interface JoopSyncStatus {\n online: boolean;\n pendingCount: number;\n syncedCount: number;\n failedCount: number;\n lastSyncAt: number | null;\n syncing: boolean;\n}\n\nexport class JoopSyncEngine {\n private _cfg: JoopSyncConfig | null = null;\n private _mutations: JoopMutation[] = [];\n private _conflicts: JoopSyncConflict[] = [];\n private _syncing = false;\n private _syncedCount = 0;\n private _lastSyncAt: number | null = null;\n private _online = typeof navigator !== 'undefined' ? navigator.onLine : true;\n private _status$ = new JoopBehaviorSubject<JoopSyncStatus>(this._buildStatus());\n private _conflict$ = new JoopSubject<JoopSyncConflict>();\n private _onlineHandlers: Array<() => void> = [];\n\n configure(config: JoopSyncConfig): void {\n this._cfg = config;\n if (typeof window !== 'undefined') {\n const onOnline = () => { this._online = true; this._updateStatus(); this.sync(); };\n const onOffline = () => { this._online = false; this._updateStatus(); };\n window.addEventListener('online', onOnline);\n window.addEventListener('offline', onOffline);\n this._onlineHandlers.push(\n () => window.removeEventListener('online', onOnline),\n () => window.removeEventListener('offline', onOffline),\n );\n }\n }\n\n destroy(): void { for (const rm of this._onlineHandlers) rm(); this._onlineHandlers = []; }\n\n mutate(type: string, payload: unknown): JoopMutation {\n const m: JoopMutation = { id: _uid(), type, payload, status: 'pending', timestamp: Date.now(), retries: 0 };\n this._mutations.push(m);\n this._updateStatus();\n if (this._online && !this._syncing) this.sync();\n return m;\n }\n\n pending(): JoopMutation[] { return this._mutations.filter(m => m.status === 'pending' || m.status === 'failed'); }\n conflicts(): JoopSyncConflict[] { return [...this._conflicts]; }\n status$() { return this._status$.asObservable(); }\n conflict$() { return this._conflict$.asObservable(); }\n\n async sync(): Promise<void> {\n if (!this._cfg || this._syncing || !this._online) return;\n const pending = this.pending();\n if (pending.length === 0) return;\n\n this._syncing = true;\n this._updateStatus();\n\n const { syncUrl, headers = {}, maxRetries = 3, batchSize = 50 } = this._cfg;\n const batch = pending.slice(0, batchSize);\n\n try {\n for (const m of batch) m.status = 'syncing';\n const res = await fetch(syncUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({ mutations: batch.map(m => ({ id: m.id, type: m.type, payload: m.payload, timestamp: m.timestamp })) }),\n });\n\n if (!res.ok) throw new Error(`Sync failed: ${res.status}`);\n const data = (await res.json()) as { results: Array<{ id: string; status: 'ok' | 'conflict'; remote?: unknown }> };\n\n for (const result of data.results ?? []) {\n const m = this._mutations.find(x => x.id === result.id);\n if (!m) continue;\n if (result.status === 'ok') {\n m.status = 'synced'; this._syncedCount++;\n } else if (result.status === 'conflict') {\n m.status = 'failed';\n const conflict: JoopSyncConflict = { id: _uid(), mutationId: m.id, local: m.payload, remote: result.remote };\n this._conflicts.push(conflict);\n this._conflict$.next(conflict);\n }\n }\n } catch {\n for (const m of batch) {\n m.retries++; m.status = m.retries >= maxRetries ? 'failed' : 'pending';\n }\n } finally {\n this._syncing = false;\n this._lastSyncAt = Date.now();\n this._updateStatus();\n }\n }\n\n resolve(conflictId: string, strategy: 'local' | 'remote' | 'merge', mergeFn?: (local: unknown, remote: unknown) => unknown): void {\n const conflict = this._conflicts.find(c => c.id === conflictId);\n if (!conflict) return;\n const m = this._mutations.find(x => x.id === conflict.mutationId);\n if (m) {\n if (strategy === 'remote') m.payload = conflict.remote;\n else if (strategy === 'merge' && mergeFn) m.payload = mergeFn(conflict.local, conflict.remote);\n m.status = 'pending'; m.retries = 0;\n }\n conflict.resolvedAt = Date.now();\n conflict.resolution = strategy === 'merge' ? 'merged' : strategy;\n this._conflicts = this._conflicts.filter(c => c.id !== conflictId);\n if (this._online) this.sync();\n }\n\n clearSynced(): void { this._mutations = this._mutations.filter(m => m.status !== 'synced'); this._updateStatus(); }\n\n private _buildStatus(): JoopSyncStatus {\n return {\n online: this._online,\n pendingCount: this._mutations.filter(m => m.status === 'pending').length,\n syncedCount: this._syncedCount,\n failedCount: this._mutations.filter(m => m.status === 'failed').length,\n lastSyncAt: this._lastSyncAt,\n syncing: this._syncing,\n };\n }\n\n private _updateStatus(): void { this._status$.next(this._buildStatus()); }\n}\n\nfunction _uid(): string { return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`; }\n","// ─── G-Counter (grow-only) ───────────────────────────────────────────────────\n\nexport class CRDTCounter {\n private _inc: Record<string, number> = {};\n private _dec: Record<string, number> = {};\n\n increment(nodeId: string, by = 1): void { this._inc[nodeId] = (this._inc[nodeId] ?? 0) + by; }\n decrement(nodeId: string, by = 1): void { this._dec[nodeId] = (this._dec[nodeId] ?? 0) + by; }\n\n value(): number {\n const inc = Object.values(this._inc).reduce((s, v) => s + v, 0);\n const dec = Object.values(this._dec).reduce((s, v) => s + v, 0);\n return inc - dec;\n }\n\n merge(remote: CRDTCounter): void {\n for (const [id, v] of Object.entries(remote._inc)) this._inc[id] = Math.max(this._inc[id] ?? 0, v);\n for (const [id, v] of Object.entries(remote._dec)) this._dec[id] = Math.max(this._dec[id] ?? 0, v);\n }\n\n state(): { inc: Record<string, number>; dec: Record<string, number> } { return { inc: { ...this._inc }, dec: { ...this._dec } }; }\n\n static fromState(s: { inc: Record<string, number>; dec: Record<string, number> }): CRDTCounter {\n const c = new CRDTCounter(); c._inc = { ...s.inc }; c._dec = { ...s.dec }; return c;\n }\n}\n\n// ─── Add-Wins Set ────────────────────────────────────────────────────────────\n\nexport class CRDTSet<T> {\n private _added = new Map<string, T>();\n private _removed = new Set<string>();\n\n add(uniqueId: string, item: T): void { this._added.set(uniqueId, item); this._removed.delete(uniqueId); }\n remove(uniqueId: string): void { this._removed.add(uniqueId); }\n has(uniqueId: string): boolean { return this._added.has(uniqueId) && !this._removed.has(uniqueId); }\n values(): T[] { return Array.from(this._added.entries()).filter(([id]) => !this._removed.has(id)).map(([, v]) => v); }\n size(): number { return this.values().length; }\n\n merge(remote: CRDTSet<T>): void {\n for (const [id, item] of remote._added) if (!this._added.has(id)) this._added.set(id, item);\n for (const id of remote._removed) this._removed.add(id);\n }\n\n state(): { added: [string, T][]; removed: string[] } {\n return { added: Array.from(this._added.entries()), removed: Array.from(this._removed) };\n }\n}\n\n// ─── LWW Register (Last-Write-Wins) ─────────────────────────────────────────\n\nexport class CRDTRegister<T> {\n private _value: T;\n private _timestamp: number;\n private _nodeId: string;\n\n constructor(initial: T, nodeId = 'default', timestamp = 0) {\n this._value = initial; this._timestamp = timestamp; this._nodeId = nodeId;\n }\n\n set(value: T, nodeId: string, timestamp?: number): void {\n const ts = timestamp ?? Date.now();\n if (ts > this._timestamp || (ts === this._timestamp && nodeId > this._nodeId)) {\n this._value = value; this._timestamp = ts; this._nodeId = nodeId;\n }\n }\n\n get(): T { return this._value; }\n timestamp(): number { return this._timestamp; }\n\n merge(remote: CRDTRegister<T>): void {\n this.set(remote._value, remote._nodeId, remote._timestamp);\n }\n\n state(): { value: T; timestamp: number; nodeId: string } {\n return { value: this._value, timestamp: this._timestamp, nodeId: this._nodeId };\n }\n}\n\n// ─── CRDT Text (basic sequence CRDT — simplified RGA) ────────────────────────\n\ninterface _Char {\n id: string; // nodeId:seqNo\n char: string;\n after: string | null; // id of predecessor (null = beginning)\n deleted: boolean;\n}\n\nexport class CRDTText {\n private _chars: _Char[] = [];\n private _index = new Map<string, _Char>();\n\n insert(after: string | null, char: string, nodeId: string, seq: number): string {\n const id = `${nodeId}:${seq}`;\n const c: _Char = { id, char, after, deleted: false };\n const pos = after === null ? 0 : this._chars.findIndex(ch => ch.id === after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(id, c);\n return id;\n }\n\n delete(id: string): void {\n const c = this._index.get(id);\n if (c) c.deleted = true;\n }\n\n toString(): string { return this._chars.filter(c => !c.deleted).map(c => c.char).join(''); }\n length(): number { return this._chars.filter(c => !c.deleted).length; }\n\n merge(remote: CRDTText): void {\n for (const rc of remote._chars) {\n if (!this._index.has(rc.id)) {\n const c: _Char = { ...rc };\n const pos = rc.after === null ? 0 : this._chars.findIndex(ch => ch.id === rc.after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(c.id, c);\n } else if (rc.deleted) {\n const existing = this._index.get(rc.id)!;\n existing.deleted = true;\n }\n }\n }\n\n state(): _Char[] { return this._chars.map(c => ({ ...c })); }\n}\n\n// ─── Merge helper ────────────────────────────────────────────────────────────\n\nexport function mergeCRDT<T extends { merge(remote: T): void }>(local: T, remote: T): T {\n local.merge(remote);\n return local;\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { J as JoopObservable } from './index-Dz0gOur2.js';
|
|
2
|
+
|
|
3
|
+
type JoopSyncConflictStrategy = 'local-wins' | 'remote-wins' | 'merge';
|
|
4
|
+
interface JoopSyncConfig {
|
|
5
|
+
syncUrl: string;
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
retryMs?: number;
|
|
8
|
+
maxRetries?: number;
|
|
9
|
+
conflictStrategy?: JoopSyncConflictStrategy;
|
|
10
|
+
batchSize?: number;
|
|
11
|
+
}
|
|
12
|
+
interface JoopMutation {
|
|
13
|
+
id: string;
|
|
14
|
+
type: string;
|
|
15
|
+
payload: unknown;
|
|
16
|
+
status: 'pending' | 'syncing' | 'synced' | 'failed';
|
|
17
|
+
timestamp: number;
|
|
18
|
+
retries: number;
|
|
19
|
+
}
|
|
20
|
+
interface JoopSyncConflict {
|
|
21
|
+
id: string;
|
|
22
|
+
mutationId: string;
|
|
23
|
+
local: unknown;
|
|
24
|
+
remote: unknown;
|
|
25
|
+
resolvedAt?: number;
|
|
26
|
+
resolution?: 'local' | 'remote' | 'merged';
|
|
27
|
+
}
|
|
28
|
+
interface JoopSyncStatus {
|
|
29
|
+
online: boolean;
|
|
30
|
+
pendingCount: number;
|
|
31
|
+
syncedCount: number;
|
|
32
|
+
failedCount: number;
|
|
33
|
+
lastSyncAt: number | null;
|
|
34
|
+
syncing: boolean;
|
|
35
|
+
}
|
|
36
|
+
declare class JoopSyncEngine {
|
|
37
|
+
private _cfg;
|
|
38
|
+
private _mutations;
|
|
39
|
+
private _conflicts;
|
|
40
|
+
private _syncing;
|
|
41
|
+
private _syncedCount;
|
|
42
|
+
private _lastSyncAt;
|
|
43
|
+
private _online;
|
|
44
|
+
private _status$;
|
|
45
|
+
private _conflict$;
|
|
46
|
+
private _onlineHandlers;
|
|
47
|
+
configure(config: JoopSyncConfig): void;
|
|
48
|
+
destroy(): void;
|
|
49
|
+
mutate(type: string, payload: unknown): JoopMutation;
|
|
50
|
+
pending(): JoopMutation[];
|
|
51
|
+
conflicts(): JoopSyncConflict[];
|
|
52
|
+
status$(): JoopObservable<JoopSyncStatus>;
|
|
53
|
+
conflict$(): JoopObservable<JoopSyncConflict>;
|
|
54
|
+
sync(): Promise<void>;
|
|
55
|
+
resolve(conflictId: string, strategy: 'local' | 'remote' | 'merge', mergeFn?: (local: unknown, remote: unknown) => unknown): void;
|
|
56
|
+
clearSynced(): void;
|
|
57
|
+
private _buildStatus;
|
|
58
|
+
private _updateStatus;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { JoopSyncEngine as J, type JoopMutation as a, type JoopSyncConfig as b, type JoopSyncConflict as c, type JoopSyncStatus as d };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { J as JoopObservable } from './index-Dz0gOur2.mjs';
|
|
2
|
+
|
|
3
|
+
type JoopSyncConflictStrategy = 'local-wins' | 'remote-wins' | 'merge';
|
|
4
|
+
interface JoopSyncConfig {
|
|
5
|
+
syncUrl: string;
|
|
6
|
+
headers?: Record<string, string>;
|
|
7
|
+
retryMs?: number;
|
|
8
|
+
maxRetries?: number;
|
|
9
|
+
conflictStrategy?: JoopSyncConflictStrategy;
|
|
10
|
+
batchSize?: number;
|
|
11
|
+
}
|
|
12
|
+
interface JoopMutation {
|
|
13
|
+
id: string;
|
|
14
|
+
type: string;
|
|
15
|
+
payload: unknown;
|
|
16
|
+
status: 'pending' | 'syncing' | 'synced' | 'failed';
|
|
17
|
+
timestamp: number;
|
|
18
|
+
retries: number;
|
|
19
|
+
}
|
|
20
|
+
interface JoopSyncConflict {
|
|
21
|
+
id: string;
|
|
22
|
+
mutationId: string;
|
|
23
|
+
local: unknown;
|
|
24
|
+
remote: unknown;
|
|
25
|
+
resolvedAt?: number;
|
|
26
|
+
resolution?: 'local' | 'remote' | 'merged';
|
|
27
|
+
}
|
|
28
|
+
interface JoopSyncStatus {
|
|
29
|
+
online: boolean;
|
|
30
|
+
pendingCount: number;
|
|
31
|
+
syncedCount: number;
|
|
32
|
+
failedCount: number;
|
|
33
|
+
lastSyncAt: number | null;
|
|
34
|
+
syncing: boolean;
|
|
35
|
+
}
|
|
36
|
+
declare class JoopSyncEngine {
|
|
37
|
+
private _cfg;
|
|
38
|
+
private _mutations;
|
|
39
|
+
private _conflicts;
|
|
40
|
+
private _syncing;
|
|
41
|
+
private _syncedCount;
|
|
42
|
+
private _lastSyncAt;
|
|
43
|
+
private _online;
|
|
44
|
+
private _status$;
|
|
45
|
+
private _conflict$;
|
|
46
|
+
private _onlineHandlers;
|
|
47
|
+
configure(config: JoopSyncConfig): void;
|
|
48
|
+
destroy(): void;
|
|
49
|
+
mutate(type: string, payload: unknown): JoopMutation;
|
|
50
|
+
pending(): JoopMutation[];
|
|
51
|
+
conflicts(): JoopSyncConflict[];
|
|
52
|
+
status$(): JoopObservable<JoopSyncStatus>;
|
|
53
|
+
conflict$(): JoopObservable<JoopSyncConflict>;
|
|
54
|
+
sync(): Promise<void>;
|
|
55
|
+
resolve(conflictId: string, strategy: 'local' | 'remote' | 'merge', mergeFn?: (local: unknown, remote: unknown) => unknown): void;
|
|
56
|
+
clearSynced(): void;
|
|
57
|
+
private _buildStatus;
|
|
58
|
+
private _updateStatus;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { JoopSyncEngine as J, type JoopMutation as a, type JoopSyncConfig as b, type JoopSyncConflict as c, type JoopSyncStatus as d };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { J as JoopObservable } from '../index-Dz0gOur2.mjs';
|
|
2
|
+
|
|
3
|
+
interface JoopThemeColor {
|
|
4
|
+
name: string;
|
|
5
|
+
value: string;
|
|
6
|
+
contrastText?: string;
|
|
7
|
+
}
|
|
8
|
+
interface JoopThemePalette {
|
|
9
|
+
name: string;
|
|
10
|
+
prefix: string;
|
|
11
|
+
contrastPrefix?: string;
|
|
12
|
+
baseColor?: string;
|
|
13
|
+
colors: JoopThemeColor[];
|
|
14
|
+
}
|
|
15
|
+
interface JoopTheme {
|
|
16
|
+
id: number;
|
|
17
|
+
themeName: string;
|
|
18
|
+
palettes: JoopThemePalette[];
|
|
19
|
+
isDefault?: boolean;
|
|
20
|
+
fontFamily?: string;
|
|
21
|
+
fontSize?: string;
|
|
22
|
+
}
|
|
23
|
+
interface JoopThemeInfo {
|
|
24
|
+
id: number;
|
|
25
|
+
themeName: string;
|
|
26
|
+
primary: string;
|
|
27
|
+
}
|
|
28
|
+
declare class JoopThemeService {
|
|
29
|
+
private _themes;
|
|
30
|
+
private _active$;
|
|
31
|
+
private _id$;
|
|
32
|
+
load(themesOrUrl: JoopTheme[] | string): Promise<JoopTheme[]>;
|
|
33
|
+
getAll(): JoopTheme[];
|
|
34
|
+
getDefault(): JoopTheme | undefined;
|
|
35
|
+
getByName(name: string): JoopTheme | undefined;
|
|
36
|
+
getById(id: number): JoopTheme | undefined;
|
|
37
|
+
getMapped(): JoopThemeInfo[];
|
|
38
|
+
/** Inject a theme's palette as CSS custom properties on :root */
|
|
39
|
+
apply(theme: JoopTheme | string): void;
|
|
40
|
+
applyById(id: number): void;
|
|
41
|
+
applyDefault(): void;
|
|
42
|
+
/** Apply arbitrary CSS custom properties to :root */
|
|
43
|
+
applyVars(vars: Record<string, string>): void;
|
|
44
|
+
getActiveName(): string;
|
|
45
|
+
getActiveId(): number;
|
|
46
|
+
active$(): JoopObservable<string>;
|
|
47
|
+
activeId$(): JoopObservable<number>;
|
|
48
|
+
clearStyles(): void;
|
|
49
|
+
private _buildCssVars;
|
|
50
|
+
private _injectStyles;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { type JoopTheme, type JoopThemeColor, type JoopThemeInfo, type JoopThemePalette, JoopThemeService };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { J as JoopObservable } from '../index-Dz0gOur2.js';
|
|
2
|
+
|
|
3
|
+
interface JoopThemeColor {
|
|
4
|
+
name: string;
|
|
5
|
+
value: string;
|
|
6
|
+
contrastText?: string;
|
|
7
|
+
}
|
|
8
|
+
interface JoopThemePalette {
|
|
9
|
+
name: string;
|
|
10
|
+
prefix: string;
|
|
11
|
+
contrastPrefix?: string;
|
|
12
|
+
baseColor?: string;
|
|
13
|
+
colors: JoopThemeColor[];
|
|
14
|
+
}
|
|
15
|
+
interface JoopTheme {
|
|
16
|
+
id: number;
|
|
17
|
+
themeName: string;
|
|
18
|
+
palettes: JoopThemePalette[];
|
|
19
|
+
isDefault?: boolean;
|
|
20
|
+
fontFamily?: string;
|
|
21
|
+
fontSize?: string;
|
|
22
|
+
}
|
|
23
|
+
interface JoopThemeInfo {
|
|
24
|
+
id: number;
|
|
25
|
+
themeName: string;
|
|
26
|
+
primary: string;
|
|
27
|
+
}
|
|
28
|
+
declare class JoopThemeService {
|
|
29
|
+
private _themes;
|
|
30
|
+
private _active$;
|
|
31
|
+
private _id$;
|
|
32
|
+
load(themesOrUrl: JoopTheme[] | string): Promise<JoopTheme[]>;
|
|
33
|
+
getAll(): JoopTheme[];
|
|
34
|
+
getDefault(): JoopTheme | undefined;
|
|
35
|
+
getByName(name: string): JoopTheme | undefined;
|
|
36
|
+
getById(id: number): JoopTheme | undefined;
|
|
37
|
+
getMapped(): JoopThemeInfo[];
|
|
38
|
+
/** Inject a theme's palette as CSS custom properties on :root */
|
|
39
|
+
apply(theme: JoopTheme | string): void;
|
|
40
|
+
applyById(id: number): void;
|
|
41
|
+
applyDefault(): void;
|
|
42
|
+
/** Apply arbitrary CSS custom properties to :root */
|
|
43
|
+
applyVars(vars: Record<string, string>): void;
|
|
44
|
+
getActiveName(): string;
|
|
45
|
+
getActiveId(): number;
|
|
46
|
+
active$(): JoopObservable<string>;
|
|
47
|
+
activeId$(): JoopObservable<number>;
|
|
48
|
+
clearStyles(): void;
|
|
49
|
+
private _buildCssVars;
|
|
50
|
+
private _injectStyles;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { type JoopTheme, type JoopThemeColor, type JoopThemeInfo, type JoopThemePalette, JoopThemeService };
|