@aerogel/plugin-local-first 0.0.0-next.020894e17f1efa306d7e18794314d1f529cfc8a5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aerogel-plugin-local-first.d.ts +298 -0
- package/dist/aerogel-plugin-local-first.js +1653 -0
- package/dist/aerogel-plugin-local-first.js.map +1 -0
- package/package.json +50 -0
- package/src/components/Account.vue +9 -0
- package/src/components/AccountLoggedIn.vue +85 -0
- package/src/components/AccountLoggedOut.vue +26 -0
- package/src/components/AccountLoginModal.vue +36 -0
- package/src/components/AccountModal.vue +206 -0
- package/src/components/index.ts +5 -0
- package/src/components/settings/PurgeData.vue +43 -0
- package/src/components/settings/index.ts +10 -0
- package/src/index.css +1 -0
- package/src/index.ts +33 -0
- package/src/jobs/Backup.ts +98 -0
- package/src/jobs/Migrate.test.ts +217 -0
- package/src/jobs/Migrate.ts +179 -0
- package/src/jobs/Sync.test.ts +1198 -0
- package/src/jobs/Sync.ts +697 -0
- package/src/jobs/mixins/LoadsChildren.ts +229 -0
- package/src/jobs/mixins/LoadsTypeIndex.ts +25 -0
- package/src/jobs/mixins/TracksLocalModels.ts +32 -0
- package/src/lib/SyncQueue.ts +94 -0
- package/src/lib/inference.ts +124 -0
- package/src/lib/mirroring.ts +348 -0
- package/src/lib/utils.ts +21 -0
- package/src/services/Cloud.state.ts +111 -0
- package/src/services/Cloud.ts +494 -0
- package/src/services/DocumentsCache.ts +39 -0
- package/src/testing/cloud.ts +193 -0
- package/src/testing/mocks/Solid.mock.ts +34 -0
- package/src/testing/setup.ts +33 -0
- package/src/testing/stubs/LegacyTask.schema.ts +15 -0
- package/src/testing/stubs/Movie.schema.ts +15 -0
- package/src/testing/stubs/Movie.ts +3 -0
- package/src/testing/stubs/MoviesContainer.ts +20 -0
- package/src/testing/stubs/Person.schema.ts +9 -0
- package/src/testing/stubs/Person.ts +18 -0
- package/src/testing/stubs/Post.schema.ts +17 -0
- package/src/testing/stubs/Post.ts +18 -0
- package/src/testing/stubs/Task.schema.ts +12 -0
- package/src/testing/stubs/Task.ts +3 -0
- package/src/testing/stubs/TasksList.ts +20 -0
- package/src/testing/stubs/Workspace.ts +15 -0
- package/src/types/shims.d.ts +7 -0
|
@@ -0,0 +1,1653 @@
|
|
|
1
|
+
var Ze = Object.defineProperty;
|
|
2
|
+
var Ge = (o, s, e) => s in o ? Ze(o, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[s] = e;
|
|
3
|
+
var w = (o, s, e) => Ge(o, typeof s != "symbol" ? s + "" : s, e);
|
|
4
|
+
import { Service as Xe, Events as D, App as se, Job as ye, Errors as Z, defineServiceState as et, replaceExisting as ve, translateWithDefault as $, dispatch as re, Modal as ze, Markdown as T, Link as ue, Button as q, UI as ae, Storage as tt, defineSettings as nt, useEvent as st, SettingsModal as Ee, ProgressBar as ot, AdvancedOptions as it, Checkbox as le, EditableContent as rt, DropdownMenu as at, bootServices as lt } from "@aerogel/core";
|
|
5
|
+
import { facade as we, IndexedDBMap as ct, arrayFilter as dt, isInstanceOf as E, after as G, arrayRemove as ut, required as U, tap as Te, urlRoute as qe, urlResolveDirectory as ht, objectWithout as ft, requireUrlParentDirectory as X, fail as Pe, arrayFrom as mt, map as z, arrayChunk as gt, mixed as _e, objectMap as pt, round as yt, toString as wt, Semaphore as Mt, isArray as bt, isTesting as $e, hasLocationQueryParameter as Se, parseBoolean as De, getLocationQueryParameter as ke } from "@noeldemartin/utils";
|
|
6
|
+
import { Solid as C, SolidLogin as Ct, SolidAvatar as Oe } from "@aerogel/plugin-solid";
|
|
7
|
+
import { SolidModel as N, SolidContainsRelation as xe, isContainerClass as x, SolidContainer as j, SolidACLAuthorization as vt, SolidDocument as $t, Metadata as St, Operation as Dt, isContainer as L, Tombstone as W, PropertyOperation as ee, isSolidModel as kt } from "soukai-solid";
|
|
8
|
+
import { getTrackedModels as Me, trackModelsCollection as te, ignoreModelsCollection as Rt, trackModels as Lt } from "@aerogel/plugin-soukai";
|
|
9
|
+
import { watchEffect as Ut, markRaw as _, createElementBlock as M, openBlock as h, createElementVNode as f, defineComponent as B, createBlock as R, unref as d, withCtx as b, createVNode as u, createTextVNode as K, toDisplayString as S, createCommentVNode as O, useTemplateRef as At, ref as It, computed as Y, normalizeClass as zt } from "vue";
|
|
10
|
+
import { bootModels as Et, requireEngine as Tt, DocumentNotFound as qt, InvalidModelAttributes as Pt, requireBootedModel as _t, getBootedModels as Ot } from "soukai";
|
|
11
|
+
import { MalformedSolidDocumentError as xt } from "@noeldemartin/solid-utils";
|
|
12
|
+
class Jt extends Xe {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
w(this, "cache", new ct("documents-cache"));
|
|
16
|
+
}
|
|
17
|
+
async isFresh(e, t) {
|
|
18
|
+
const n = await this.cache.get(e), i = typeof t != "number" ? t.getTime() : t;
|
|
19
|
+
return !!(n != null && n.modifiedAt) && n.modifiedAt >= i;
|
|
20
|
+
}
|
|
21
|
+
async remember(e, t) {
|
|
22
|
+
await this.cache.set(e, {
|
|
23
|
+
modifiedAt: typeof t != "number" ? t.getTime() : t
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async forget(e) {
|
|
27
|
+
await this.cache.delete(e);
|
|
28
|
+
}
|
|
29
|
+
async clear() {
|
|
30
|
+
await this.cache.clear();
|
|
31
|
+
}
|
|
32
|
+
async boot() {
|
|
33
|
+
D.on("auth:logout", async () => {
|
|
34
|
+
await this.cache.clear(), this.cache.close();
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const P = we(Jt), ce = /* @__PURE__ */ new WeakMap();
|
|
39
|
+
function he(o) {
|
|
40
|
+
return dt(
|
|
41
|
+
k(o).map((s) => {
|
|
42
|
+
const e = o.instance().requireRelation(s).relatedClass;
|
|
43
|
+
return x(e) ? !1 : e;
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function k(o) {
|
|
48
|
+
return ce.has(o) || ce.set(
|
|
49
|
+
o,
|
|
50
|
+
o.relations.filter((s) => N.reservedRelations.includes(s) ? !1 : o.instance().requireRelation(s) instanceof xe)
|
|
51
|
+
), ce.get(o) ?? [];
|
|
52
|
+
}
|
|
53
|
+
function Je(o) {
|
|
54
|
+
return k(o.static()).reduce(
|
|
55
|
+
(e, t) => e.concat(o.getRelationModels(t) ?? []),
|
|
56
|
+
[]
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
function Re(o) {
|
|
60
|
+
const s = /* @__PURE__ */ new Set(), e = o.instance();
|
|
61
|
+
s.add(o);
|
|
62
|
+
for (const t of o.relations)
|
|
63
|
+
o.reservedRelations.includes(t) || s.add(e.requireRelation(t).relatedClass);
|
|
64
|
+
return [...s.values()];
|
|
65
|
+
}
|
|
66
|
+
function fe(o) {
|
|
67
|
+
return o.getRelatedModels().filter(
|
|
68
|
+
(s) => !E(s, vt) && !E(s, $t) && !E(s, St) && !E(s, Dt) && s.static() !== j
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
function Ne(o) {
|
|
72
|
+
if (o.isDirty())
|
|
73
|
+
return !0;
|
|
74
|
+
if (!(o instanceof j))
|
|
75
|
+
return !1;
|
|
76
|
+
const s = (e) => {
|
|
77
|
+
var t;
|
|
78
|
+
return (t = o.getRelationModels(e)) == null ? void 0 : t.some((n) => Ne(n));
|
|
79
|
+
};
|
|
80
|
+
return k(o.static()).some(s);
|
|
81
|
+
}
|
|
82
|
+
const Nt = U(() => se.service("$cloud"));
|
|
83
|
+
class Wt {
|
|
84
|
+
constructor() {
|
|
85
|
+
w(this, "models", /* @__PURE__ */ new Set());
|
|
86
|
+
w(this, "promises", []);
|
|
87
|
+
}
|
|
88
|
+
push(s) {
|
|
89
|
+
this.models.add(s), this.syncAfter(G({ seconds: 1 }));
|
|
90
|
+
}
|
|
91
|
+
clear(s) {
|
|
92
|
+
if (!s) {
|
|
93
|
+
this.models = /* @__PURE__ */ new Set();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
for (const e of s)
|
|
97
|
+
this.models.delete(e);
|
|
98
|
+
}
|
|
99
|
+
async syncAfter(s) {
|
|
100
|
+
const e = typeof s == "function" ? s() : s;
|
|
101
|
+
return this.promises.push(e), e.then(() => ut(this.promises, e)), this.promises.length === 1 && this.schedule(), e;
|
|
102
|
+
}
|
|
103
|
+
schedule() {
|
|
104
|
+
Promise.all(this.promises).then(() => G()).then(() => {
|
|
105
|
+
if (this.promises.length !== 0) {
|
|
106
|
+
this.schedule();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const s = this.consume();
|
|
110
|
+
s.length !== 0 && Nt.syncIfOnline(s);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
consume() {
|
|
114
|
+
const s = [], e = /* @__PURE__ */ new Set();
|
|
115
|
+
for (const t of this.models)
|
|
116
|
+
L(t) && (this.models.delete(t), Je(t).forEach((n) => e.add(n)), s.push(t));
|
|
117
|
+
for (const t of this.models)
|
|
118
|
+
this.models.delete(t), !e.has(t) && s.push(t);
|
|
119
|
+
return s;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const ne = we(Wt), y = U(() => se.service("$cloud")), We = /* @__PURE__ */ new WeakMap(), be = /* @__PURE__ */ new WeakMap();
|
|
123
|
+
function jt(o) {
|
|
124
|
+
const s = o.getRelatedModels().concat([o]);
|
|
125
|
+
for (const e of s)
|
|
126
|
+
e.cleanDirty(!0);
|
|
127
|
+
}
|
|
128
|
+
function Bt(o) {
|
|
129
|
+
const s = fe(o).concat([o]);
|
|
130
|
+
for (const e of s) {
|
|
131
|
+
if (!e.operations || e.operations.length === 0)
|
|
132
|
+
continue;
|
|
133
|
+
const t = (e.operations ?? []).filter((n) => !(n instanceof ee) || !e.ignoreRdfPropertyHistory(n.property, !0));
|
|
134
|
+
if (!t.some((n) => !n.isInception(e))) {
|
|
135
|
+
e.setRelationModels("operations", []);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
e.setRelationModels("operations", t);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async function Le(o) {
|
|
142
|
+
y.setState({
|
|
143
|
+
localModelUpdates: {
|
|
144
|
+
...y.localModelUpdates,
|
|
145
|
+
[o.url]: 1
|
|
146
|
+
}
|
|
147
|
+
}), Gt(o.static()) && await me(o.static(), X(o.url)), y.autoPush && y.ready && !y.syncing && ne.push(o);
|
|
148
|
+
}
|
|
149
|
+
async function me(o, s) {
|
|
150
|
+
var e, t;
|
|
151
|
+
(e = y.modelCollections[o.modelName]) != null && e.includes(s) || (y.setState("modelCollections", {
|
|
152
|
+
...y.modelCollections,
|
|
153
|
+
[o.modelName]: (y.modelCollections[o.modelName] ?? []).concat(s)
|
|
154
|
+
}), (t = y.modelCollections[o.modelName]) != null && t.includes(o.collection) || (o.collection = s), await te(o, s));
|
|
155
|
+
}
|
|
156
|
+
async function Ue(o) {
|
|
157
|
+
if (Vt(o))
|
|
158
|
+
return;
|
|
159
|
+
const s = y.localModelUpdates[o.url] ?? 0;
|
|
160
|
+
y.setState({
|
|
161
|
+
localModelUpdates: o.isSoftDeleted() ? ft(y.localModelUpdates, o.url) : {
|
|
162
|
+
...y.localModelUpdates,
|
|
163
|
+
[o.url]: s + 1
|
|
164
|
+
}
|
|
165
|
+
}), await P.forget(o.requireDocumentUrl()), y.autoPush && y.ready && !y.syncing && ne.push(o);
|
|
166
|
+
}
|
|
167
|
+
function ge(o, s) {
|
|
168
|
+
const e = {}, t = Array.from(o);
|
|
169
|
+
for (const [n, i] of Object.entries(y.localModelUpdates)) {
|
|
170
|
+
const l = qe(n);
|
|
171
|
+
(o.has(n) || t.some((r) => r.endsWith("/") && n.startsWith(r))) && !(s != null && s.has(l)) || (e[n] = i);
|
|
172
|
+
}
|
|
173
|
+
y.setState({ localModelUpdates: e });
|
|
174
|
+
}
|
|
175
|
+
function Ce(o, s = {}) {
|
|
176
|
+
const e = /* @__PURE__ */ new Set();
|
|
177
|
+
if (e.add(o.static()), o instanceof j)
|
|
178
|
+
for (const n of k(o.static()))
|
|
179
|
+
e.add(o.requireRelation(n).relatedClass);
|
|
180
|
+
const t = [...e.values()].map(
|
|
181
|
+
(n) => [n, I(n)]
|
|
182
|
+
);
|
|
183
|
+
return Te(o.clone({ constructors: t }), (n) => {
|
|
184
|
+
Bt(n), s.clean && jt(n);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
function je(o) {
|
|
188
|
+
const s = /* @__PURE__ */ new Set();
|
|
189
|
+
if (s.add(o.static()), o instanceof j)
|
|
190
|
+
for (const t of k(o.static()))
|
|
191
|
+
s.add(o.requireRelation(t).relatedClass);
|
|
192
|
+
const e = [...s.values()].map(
|
|
193
|
+
(t) => [t, en(t)]
|
|
194
|
+
);
|
|
195
|
+
return o.clone({ constructors: e });
|
|
196
|
+
}
|
|
197
|
+
async function Ae(o, s, e) {
|
|
198
|
+
const t = I(W), n = s.map((a) => a.url), i = o.filter((a) => !n.includes(a.url)).map((a) => a.requireDocumentUrl()).filter((a) => !e.has(a)), l = await t.all({ $in: i });
|
|
199
|
+
return s.concat(l);
|
|
200
|
+
}
|
|
201
|
+
function Vt(o) {
|
|
202
|
+
var e;
|
|
203
|
+
const s = (e = o.metadata.updatedAt) == null ? void 0 : e.getTime();
|
|
204
|
+
return !o.operations.some((t) => t.date.getTime() !== s ? !1 : t instanceof ee ? !o.ignoreRdfPropertyHistory(t.property, !0) : !0);
|
|
205
|
+
}
|
|
206
|
+
function Ft(o, s) {
|
|
207
|
+
return s.get(o.url) ?? je(o);
|
|
208
|
+
}
|
|
209
|
+
function pe() {
|
|
210
|
+
return [...y.registeredModels].map(({ modelClass: o }) => Me(o, { includeSoftDeleted: !0 })).flat();
|
|
211
|
+
}
|
|
212
|
+
function Ht() {
|
|
213
|
+
return y.schemaMigrations;
|
|
214
|
+
}
|
|
215
|
+
function Kt() {
|
|
216
|
+
y.schemaMigrations.clear();
|
|
217
|
+
}
|
|
218
|
+
function Ie(o) {
|
|
219
|
+
return y.schemaMigrations.get(o);
|
|
220
|
+
}
|
|
221
|
+
function I(o) {
|
|
222
|
+
return We.get(o) ?? Xt(o);
|
|
223
|
+
}
|
|
224
|
+
function de(o, s) {
|
|
225
|
+
const e = C.requireUser().storageUrls[0], t = x(o) && k(o).map((n) => {
|
|
226
|
+
const i = o.instance().requireRelation(n).relatedClass;
|
|
227
|
+
return x(i) ? null : i;
|
|
228
|
+
}).filter(Boolean)[0];
|
|
229
|
+
return s ?? (s = `/${(t || o).modelName.toLowerCase()}s/`), ht((s.startsWith("/") ? e.slice(0, -1) : e) + s);
|
|
230
|
+
}
|
|
231
|
+
function Yt(o, s) {
|
|
232
|
+
return s.get(o.url) ?? Ce(o);
|
|
233
|
+
}
|
|
234
|
+
function Qt(o) {
|
|
235
|
+
for (const { modelClass: s } of y.registeredModels)
|
|
236
|
+
if (Me(s).some((t) => t.url === o.url))
|
|
237
|
+
return !0;
|
|
238
|
+
return !1;
|
|
239
|
+
}
|
|
240
|
+
function Q(o) {
|
|
241
|
+
return be.has(o.static());
|
|
242
|
+
}
|
|
243
|
+
function Zt(o) {
|
|
244
|
+
return !Q(o);
|
|
245
|
+
}
|
|
246
|
+
function Gt(o) {
|
|
247
|
+
return y.registeredModels.some(({ modelClass: s }) => s === o);
|
|
248
|
+
}
|
|
249
|
+
function Xt(o) {
|
|
250
|
+
var n;
|
|
251
|
+
const s = o, e = (i, l) => {
|
|
252
|
+
i.timestamps = s.timestamps, i.history = s.history, l(), i.timestamps = [], i.history = !1;
|
|
253
|
+
}, t = (n = class extends s {
|
|
254
|
+
initialize(i, l) {
|
|
255
|
+
e(this._proxy.static(), () => super.initialize(i, l));
|
|
256
|
+
}
|
|
257
|
+
initializeRelations() {
|
|
258
|
+
super.initializeRelations();
|
|
259
|
+
for (const i of Object.values(this._relations))
|
|
260
|
+
i instanceof xe && (i.relatedClass = I(i.relatedClass));
|
|
261
|
+
}
|
|
262
|
+
fixMalformedAttributes() {
|
|
263
|
+
e(this.static(), () => super.fixMalformedAttributes());
|
|
264
|
+
}
|
|
265
|
+
}, w(n, "timestamps", !1), w(n, "history", !1), n);
|
|
266
|
+
return We.set(s, t), be.set(t, s), s.on("schema-updated", async (i) => {
|
|
267
|
+
await t.updateSchema({
|
|
268
|
+
...i,
|
|
269
|
+
timestamps: !1,
|
|
270
|
+
history: !1
|
|
271
|
+
});
|
|
272
|
+
}), Et({ [`Remote${o.modelName}`]: t }), t;
|
|
273
|
+
}
|
|
274
|
+
function en(o) {
|
|
275
|
+
return be.get(o) ?? Pe(`Couldn't find local class for ${o.modelName}`);
|
|
276
|
+
}
|
|
277
|
+
class tn extends ye {
|
|
278
|
+
constructor() {
|
|
279
|
+
super(...arguments);
|
|
280
|
+
w(this, "urlMigrations", []);
|
|
281
|
+
w(this, "collectionMigrations", []);
|
|
282
|
+
}
|
|
283
|
+
migrateUrl(e, t, n) {
|
|
284
|
+
this.urlMigrations.push({
|
|
285
|
+
modelClass: e,
|
|
286
|
+
local: t,
|
|
287
|
+
remote: n
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
migrateCollection(e, t, n) {
|
|
291
|
+
this.collectionMigrations.push({
|
|
292
|
+
modelClass: e,
|
|
293
|
+
local: t,
|
|
294
|
+
remote: n
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
async run() {
|
|
298
|
+
const e = Tt(), t = await e.getCollections();
|
|
299
|
+
for (const n of t) {
|
|
300
|
+
const i = await e.readMany(n);
|
|
301
|
+
for (const [l, a] of Object.entries(i)) {
|
|
302
|
+
const r = this.replaceUrl(l);
|
|
303
|
+
await e.create(X(r), this.replaceDocumentUrls(a), r), await e.delete(n, l);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
for (const { modelClass: n, remote: i } of this.urlMigrations)
|
|
307
|
+
te(n, X(i), { refresh: !1 });
|
|
308
|
+
for (const { modelClass: n, local: i, remote: l } of this.collectionMigrations)
|
|
309
|
+
Rt(n, i), te(n, l, { refresh: !1 });
|
|
310
|
+
}
|
|
311
|
+
replaceDocumentUrls(e) {
|
|
312
|
+
for (const [t, n] of Object.entries(e)) {
|
|
313
|
+
if (t === "@id" && typeof n == "string") {
|
|
314
|
+
e[t] = this.replaceUrl(n);
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
typeof n != "object" || n === null || (e[t] = this.replaceDocumentUrls(n));
|
|
318
|
+
}
|
|
319
|
+
return e;
|
|
320
|
+
}
|
|
321
|
+
replaceUrl(e) {
|
|
322
|
+
for (const { local: t, remote: n } of this.urlMigrations)
|
|
323
|
+
if (e.startsWith(t))
|
|
324
|
+
return e.replace(t, n);
|
|
325
|
+
for (const { local: t, remote: n } of this.collectionMigrations)
|
|
326
|
+
if (e.startsWith(t))
|
|
327
|
+
return e.replace(t, n);
|
|
328
|
+
return e;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function nn(o) {
|
|
332
|
+
const s = {};
|
|
333
|
+
return async () => ("value" in s || (s.value = await o()), s.value);
|
|
334
|
+
}
|
|
335
|
+
class Be {
|
|
336
|
+
async loadContainedModels(s, e = {}) {
|
|
337
|
+
var p;
|
|
338
|
+
if (Zt(s)) {
|
|
339
|
+
const m = [];
|
|
340
|
+
for (const g of k(s.static())) {
|
|
341
|
+
const J = await s.loadRelationIfUnloaded(g) ?? [];
|
|
342
|
+
m.push(...mt(J));
|
|
343
|
+
}
|
|
344
|
+
return m;
|
|
345
|
+
}
|
|
346
|
+
const t = {}, n = [], i = z(s.documents, "url"), l = gt(s.resourceUrls, 10), a = l.flat().map((m) => ({
|
|
347
|
+
documentUrl: m,
|
|
348
|
+
completed: !1
|
|
349
|
+
})), r = z(a, "documentUrl");
|
|
350
|
+
e.status && (e.status.children = a);
|
|
351
|
+
for (const m of l) {
|
|
352
|
+
await Promise.all(
|
|
353
|
+
m.map(async (g) => {
|
|
354
|
+
const { children: J, tombstones: Ye } = await this.loadDocumentChildren(
|
|
355
|
+
s,
|
|
356
|
+
g,
|
|
357
|
+
i,
|
|
358
|
+
e.onDocumentError,
|
|
359
|
+
e.onDocumentRead
|
|
360
|
+
);
|
|
361
|
+
n.push(...Ye);
|
|
362
|
+
for (const [ie, Qe] of Object.entries(J))
|
|
363
|
+
(t[ie] ?? (t[ie] = [])).push(...Qe);
|
|
364
|
+
})
|
|
365
|
+
);
|
|
366
|
+
for (const g of m)
|
|
367
|
+
g.endsWith("/") || (U(r.get(g)).completed = !0);
|
|
368
|
+
await ((p = e.onDocumentsLoaded) == null ? void 0 : p.call(e, m));
|
|
369
|
+
}
|
|
370
|
+
for (const [m, g] of Object.entries(t))
|
|
371
|
+
s.setRelationModels(m, g);
|
|
372
|
+
const c = e.ignoreTombstones ? Object.values(t).flat() : Object.values(t).flat().concat(n);
|
|
373
|
+
return e.status && (e.status.children = c.map((m) => U(r.get(m.requireDocumentUrl())))), c;
|
|
374
|
+
}
|
|
375
|
+
async loadDocumentChildren(s, e, t, n, i) {
|
|
376
|
+
var a;
|
|
377
|
+
const l = t.get(e);
|
|
378
|
+
return l && l.updatedAt && await P.isFresh(l.url, l.updatedAt) && ((a = this.localModels) != null && a.hasKey(s.url)) ? {
|
|
379
|
+
children: await this.loadDocumentChildrenFromLocal(s, l),
|
|
380
|
+
tombstones: []
|
|
381
|
+
} : this.loadDocumentChildrenFromRemote(s, e, n, i);
|
|
382
|
+
}
|
|
383
|
+
async loadDocumentChildrenFromLocal(s, e) {
|
|
384
|
+
var n, i;
|
|
385
|
+
const t = {};
|
|
386
|
+
for (const l of k(s.static())) {
|
|
387
|
+
const a = s.requireRelation(l);
|
|
388
|
+
if (a.loaded) {
|
|
389
|
+
t[l] = a.getLoadedModels();
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
const r = ((i = (n = this.localModels) == null ? void 0 : n.get(s.url)) == null ? void 0 : i.getRelationModels(l)) ?? [];
|
|
393
|
+
t[l] = r.filter((c) => c.getDocumentUrl() === e.url).map((c) => Ce(c, { clean: !0 }));
|
|
394
|
+
}
|
|
395
|
+
return t;
|
|
396
|
+
}
|
|
397
|
+
async loadDocumentChildrenFromRemote(s, e, t, n) {
|
|
398
|
+
const i = {}, l = [], a = nn(async () => {
|
|
399
|
+
try {
|
|
400
|
+
const r = s.documents.find((m) => m.url === e), c = await s.requireEngine().readOne(s.static("collection"), e), p = await W.createManyFromEngineDocuments({
|
|
401
|
+
[e]: c
|
|
402
|
+
});
|
|
403
|
+
return l.push(...p), r && (n == null || n(r)), c;
|
|
404
|
+
} catch (r) {
|
|
405
|
+
if (E(r, qt))
|
|
406
|
+
return null;
|
|
407
|
+
if (!t)
|
|
408
|
+
throw r;
|
|
409
|
+
return t(r), null;
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
for (const r of k(s.static())) {
|
|
413
|
+
const c = s.requireRelation(r);
|
|
414
|
+
if (c.loaded) {
|
|
415
|
+
i[r] = c.getLoadedModels();
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
const p = await a();
|
|
419
|
+
if (p)
|
|
420
|
+
try {
|
|
421
|
+
const m = await c.relatedClass.createManyFromEngineDocuments({
|
|
422
|
+
[e]: p
|
|
423
|
+
});
|
|
424
|
+
i[r] = m;
|
|
425
|
+
} catch (m) {
|
|
426
|
+
if (!t)
|
|
427
|
+
throw m;
|
|
428
|
+
t(m);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return { children: i, tombstones: l };
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
const V = /* @__PURE__ */ new WeakMap();
|
|
435
|
+
class Ve {
|
|
436
|
+
async loadTypeIndex(s = {}) {
|
|
437
|
+
const e = C.requireUser();
|
|
438
|
+
return (s.fresh || !V.has(e)) && V.set(e, await C.findPrivateTypeIndex({ fresh: s.fresh })), s.create && !V.get(e) && V.set(e, await C.findOrCreatePrivateTypeIndex()), V.get(e) ?? null;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
class Fe {
|
|
442
|
+
async indexLocalModels(s) {
|
|
443
|
+
for (const e of s)
|
|
444
|
+
await this.addLocalModel(e);
|
|
445
|
+
}
|
|
446
|
+
async addLocalModel(s) {
|
|
447
|
+
if (!(!this.localModels || this.localModels.hasKey(s.url))) {
|
|
448
|
+
this.localModels.add(s);
|
|
449
|
+
for (const e of k(s.static()))
|
|
450
|
+
await s.loadRelationIfUnloaded(e);
|
|
451
|
+
for (const e of s.getRelatedModels())
|
|
452
|
+
await this.addLocalModel(e);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
const sn = ye;
|
|
457
|
+
class oe extends _e(sn, [Be, Ve, Fe]) {
|
|
458
|
+
constructor() {
|
|
459
|
+
super(...arguments);
|
|
460
|
+
w(this, "_models");
|
|
461
|
+
}
|
|
462
|
+
static restore(e) {
|
|
463
|
+
return Te(new oe(), (t) => {
|
|
464
|
+
t.status = e;
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
get models() {
|
|
468
|
+
return this._models;
|
|
469
|
+
}
|
|
470
|
+
set models(e) {
|
|
471
|
+
if (!e) {
|
|
472
|
+
delete this._models, delete this.localModels;
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const t = pt(this.status.children ?? [], "modelUrl");
|
|
476
|
+
this._models = e, this.localModels = z([], "url"), this.status.children = e.map(
|
|
477
|
+
(n) => t[n.url] ?? {
|
|
478
|
+
modelUrl: n.url,
|
|
479
|
+
completed: !1
|
|
480
|
+
}
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
async run() {
|
|
484
|
+
if (!this.models)
|
|
485
|
+
throw new Error("Cant start migration without models");
|
|
486
|
+
await this.indexLocalModels(this.models);
|
|
487
|
+
const e = this.status.children ?? [], t = await this.loadTypeIndex();
|
|
488
|
+
for (const n of e) {
|
|
489
|
+
const i = this.models.find(({ url: l }) => n.modelUrl === l);
|
|
490
|
+
!i || n.completed || (await this.migrateRegisteredModel(i, n, t), await this.updateProgress(() => n.completed = !0));
|
|
491
|
+
}
|
|
492
|
+
for (const [n, i] of Ht())
|
|
493
|
+
await n.updateSchema(i);
|
|
494
|
+
Kt();
|
|
495
|
+
}
|
|
496
|
+
async migrateRegisteredModel(e, t, n) {
|
|
497
|
+
if (await this.migrate(e, t), !L(e))
|
|
498
|
+
return;
|
|
499
|
+
const i = he(e.static()), l = n == null ? void 0 : n.registrations.find(({ instanceContainer: a }) => a === e.url);
|
|
500
|
+
!n || !l || i.length === 0 || (l.setAttribute(
|
|
501
|
+
"forClass",
|
|
502
|
+
i.map((a) => {
|
|
503
|
+
var r;
|
|
504
|
+
return ((r = Ie(a)) == null ? void 0 : r.rdfsClasses) ?? a.rdfsClass;
|
|
505
|
+
}).flat()
|
|
506
|
+
), await n.save());
|
|
507
|
+
}
|
|
508
|
+
async migrate(e, t) {
|
|
509
|
+
this.assertNotCancelled(), await this.migrateChildren(e, t);
|
|
510
|
+
const n = Ie(e.static());
|
|
511
|
+
if (!n)
|
|
512
|
+
return;
|
|
513
|
+
const i = await I(e.static()).find(e.url), l = await (i == null ? void 0 : i.migrateSchema(n));
|
|
514
|
+
await e.migrateSchema(n, {
|
|
515
|
+
mintOperationUrl: (a) => {
|
|
516
|
+
var r, c;
|
|
517
|
+
return (c = (r = l == null ? void 0 : l.operations) == null ? void 0 : r.find((p) => !E(a, ee) || !E(p, ee) ? !1 : a.property === p.property && a.date.getTime() === p.date.getTime())) == null ? void 0 : c.url;
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
async migrateChildren(e, t) {
|
|
522
|
+
if (!L(e))
|
|
523
|
+
return;
|
|
524
|
+
const n = await this.loadContainedModels(e, { ignoreTombstones: !0 });
|
|
525
|
+
t.children ?? (t.children = n.map((i) => ({
|
|
526
|
+
modelUrl: i.url,
|
|
527
|
+
completed: !1
|
|
528
|
+
})));
|
|
529
|
+
for (const i of t.children) {
|
|
530
|
+
const l = n.find(({ url: a }) => i.modelUrl === a);
|
|
531
|
+
!l || i.completed || (await this.migrate(l, i), await this.updateProgress(() => i.completed = !0));
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
const on = U(() => se.service("$cloud")), rn = ye;
|
|
536
|
+
function an(o) {
|
|
537
|
+
return !!o && "root" in o;
|
|
538
|
+
}
|
|
539
|
+
class ln extends _e(rn, [Be, Ve, Fe]) {
|
|
540
|
+
constructor(e) {
|
|
541
|
+
super();
|
|
542
|
+
w(this, "models");
|
|
543
|
+
w(this, "dirtyRemoteModels");
|
|
544
|
+
w(this, "rootLocalModels");
|
|
545
|
+
w(this, "tombstones");
|
|
546
|
+
w(this, "documentsWithErrors");
|
|
547
|
+
w(this, "syncedModelUrls");
|
|
548
|
+
w(this, "documentsModifiedAt");
|
|
549
|
+
w(this, "screenLock", null);
|
|
550
|
+
w(this, "localModels");
|
|
551
|
+
this.models = e, this.rootLocalModels = [], this.localModels = z([], "url"), this.tombstones = z([], "resourceUrl"), this.documentsWithErrors = /* @__PURE__ */ new Set(), this.syncedModelUrls = /* @__PURE__ */ new Set(), this.documentsModifiedAt = {};
|
|
552
|
+
}
|
|
553
|
+
async run() {
|
|
554
|
+
const e = C.requireAuthenticator().engine, t = (i, { headers: l }, a) => {
|
|
555
|
+
const r = (l == null ? void 0 : l.get("last-modified")) ?? a;
|
|
556
|
+
!r || i.endsWith("/") || (this.documentsModifiedAt[i] = new Date(r));
|
|
557
|
+
}, n = e.listeners.add({
|
|
558
|
+
onDocumentRead: (i, l) => t(i, l),
|
|
559
|
+
onDocumentUpdated: (i, l) => t(i, l, /* @__PURE__ */ new Date())
|
|
560
|
+
});
|
|
561
|
+
try {
|
|
562
|
+
this.lockScreen(), this.rootLocalModels = this.models ?? pe(), await this.indexLocalModels(this.rootLocalModels), await this.pullChanges(), await this.pushChanges();
|
|
563
|
+
} finally {
|
|
564
|
+
this.releaseScreen(), n();
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
lockScreen() {
|
|
568
|
+
const e = navigator;
|
|
569
|
+
if (e.wakeLock)
|
|
570
|
+
try {
|
|
571
|
+
this.screenLock = e.wakeLock.request("screen").catch((t) => {
|
|
572
|
+
Z.reportDevelopmentError(t, "Could not request screen wake lock");
|
|
573
|
+
});
|
|
574
|
+
} catch (t) {
|
|
575
|
+
Z.reportDevelopmentError(t, "Could not request screen wake lock");
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
releaseScreen() {
|
|
579
|
+
this.screenLock && (this.screenLock.then((e) => e == null ? void 0 : e.release()), this.screenLock = null);
|
|
580
|
+
}
|
|
581
|
+
getInitialStatus() {
|
|
582
|
+
return {
|
|
583
|
+
root: !0,
|
|
584
|
+
completed: !1,
|
|
585
|
+
children: [{ completed: !1 }, { completed: !1 }]
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
calculateCurrentProgress(e) {
|
|
589
|
+
return e ?? (e = this.status), an(e) ? yt(
|
|
590
|
+
this.calculateCurrentProgress(e.children[0]) * 0.9 + this.calculateCurrentProgress(e.children[1]) * 0.1,
|
|
591
|
+
2
|
|
592
|
+
) : super.calculateCurrentProgress(e);
|
|
593
|
+
}
|
|
594
|
+
async pullChanges() {
|
|
595
|
+
const e = this.models ? await this.fetchRemoteModelsForLocal(this.models) : await this.fetchRemoteModels(), t = z(e, (n) => n instanceof W ? n.resourceUrl : n.url);
|
|
596
|
+
this.dirtyRemoteModels = await this.synchronizeModels(t), await this.updateProgress((n) => n.children[0].completed = !0);
|
|
597
|
+
}
|
|
598
|
+
async pushChanges() {
|
|
599
|
+
const e = this.dirtyRemoteModels ?? [], t = this.status.children[1].children = e.map(() => ({ completed: !1 }));
|
|
600
|
+
for (let n = 0; n < e.length; n++) {
|
|
601
|
+
const i = e[n], l = t[n];
|
|
602
|
+
if (i.isSoftDeleted()) {
|
|
603
|
+
i.enableHistory(), i.enableTombstone(), await i.forceDelete(), await this.updateProgress(() => l.completed = !0);
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
await this.saveModelAndChildren(i, l), await this.updateTypeRegistrations(i), await this.updateProgress(() => l.completed = !0);
|
|
607
|
+
}
|
|
608
|
+
for (const [n, i] of Object.entries(this.documentsModifiedAt))
|
|
609
|
+
await P.remember(n, i);
|
|
610
|
+
ge(this.syncedModelUrls, this.documentsWithErrors), await this.updateProgress((n) => n.children[1].completed = !0);
|
|
611
|
+
}
|
|
612
|
+
async fetchRemoteModels() {
|
|
613
|
+
const e = this.status.children[0], t = await this.loadTypeIndex({ fresh: !0 });
|
|
614
|
+
if (!t)
|
|
615
|
+
return [];
|
|
616
|
+
const n = [], i = this.getTypeRegistrations(t);
|
|
617
|
+
e.children = i.map(() => ({ completed: !1 }));
|
|
618
|
+
for (let l = 0; l < i.length; l++)
|
|
619
|
+
await this.ignoringDocumentErrors(async () => {
|
|
620
|
+
var p;
|
|
621
|
+
const { registration: a, registeredModel: r } = U(i[l]), c = I(r.modelClass);
|
|
622
|
+
if (a.instanceContainer) {
|
|
623
|
+
if (x(c)) {
|
|
624
|
+
await me(
|
|
625
|
+
r.modelClass,
|
|
626
|
+
X(a.instanceContainer)
|
|
627
|
+
);
|
|
628
|
+
const m = await c.find(a.instanceContainer);
|
|
629
|
+
m && (await this.loadChildren(m, U((p = e.children) == null ? void 0 : p[l])), n.push(m)), await this.updateProgress(() => {
|
|
630
|
+
var g;
|
|
631
|
+
return U((g = e.children) == null ? void 0 : g[l]).completed = !0;
|
|
632
|
+
});
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
await me(r.modelClass, a.instanceContainer), n.push(...await c.from(a.instanceContainer).all()), await this.updateProgress(() => {
|
|
636
|
+
var m;
|
|
637
|
+
return U((m = e.children) == null ? void 0 : m[l]).completed = !0;
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
return Ae(this.rootLocalModels, n, this.documentsWithErrors);
|
|
642
|
+
}
|
|
643
|
+
async fetchRemoteModelsForLocal(e) {
|
|
644
|
+
const t = [], n = this.status.children[0].children = e.map(() => ({ completed: !1 }));
|
|
645
|
+
for (let i = 0; i < e.length; i++)
|
|
646
|
+
await this.ignoringDocumentErrors(async () => {
|
|
647
|
+
const l = e[i], a = n[i], r = await I(l.static()).find(l.url);
|
|
648
|
+
if (!r) {
|
|
649
|
+
await this.updateProgress(() => a.completed = !0);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
L(r) && await this.loadChildren(r, a), t.push(r), await this.updateProgress(() => a.completed = !0);
|
|
653
|
+
});
|
|
654
|
+
return Ae(e, t, this.documentsWithErrors);
|
|
655
|
+
}
|
|
656
|
+
getTypeRegistrations(e) {
|
|
657
|
+
const t = /* @__PURE__ */ new Set(), n = [...on.registeredModels].map(({ modelClass: a }) => {
|
|
658
|
+
const r = x(a) ? he(a) : [];
|
|
659
|
+
return {
|
|
660
|
+
modelClass: a,
|
|
661
|
+
rdfsClasses: r.length > 0 ? r.map((c) => c.rdfsClasses).flat() : a.rdfsClasses
|
|
662
|
+
};
|
|
663
|
+
}), i = e.registrations.map((a) => {
|
|
664
|
+
const r = n.find(
|
|
665
|
+
({ rdfsClasses: c }) => !!a.instanceContainer && c.some((p) => a.forClass.includes(p))
|
|
666
|
+
);
|
|
667
|
+
return !r || !a.instanceContainer || t.has(a.instanceContainer) ? null : (t.add(a.instanceContainer), { registration: a, registeredModel: r });
|
|
668
|
+
}).filter((a) => !!a), l = i.map(({ registration: a }) => a.instanceContainer);
|
|
669
|
+
return i.filter(({ registration: a }) => !l.some(
|
|
670
|
+
(r) => {
|
|
671
|
+
var c;
|
|
672
|
+
return r && r !== a.instanceContainer && ((c = a.instanceContainer) == null ? void 0 : c.startsWith(r));
|
|
673
|
+
}
|
|
674
|
+
));
|
|
675
|
+
}
|
|
676
|
+
async updateTypeRegistrations(e) {
|
|
677
|
+
if (!Qt(e))
|
|
678
|
+
return;
|
|
679
|
+
const t = L(e) ? he(e.static()) : [e.static()], n = I(j), i = L(e) ? e : new n({ url: e.requireContainerUrl() });
|
|
680
|
+
if (t.length === 0)
|
|
681
|
+
return;
|
|
682
|
+
const l = await this.loadTypeIndex({ create: !0 });
|
|
683
|
+
l.registrations.some((a) => a.instanceContainer === e.url) || await i.register(l, t);
|
|
684
|
+
}
|
|
685
|
+
async loadChildren(e, t) {
|
|
686
|
+
var i, l;
|
|
687
|
+
if (this.assertNotCancelled(), !L(e))
|
|
688
|
+
return;
|
|
689
|
+
const n = await this.loadContainedModels(e, {
|
|
690
|
+
status: t,
|
|
691
|
+
onDocumentError: (a) => this.handleDocumentError(a),
|
|
692
|
+
onDocumentRead: (a) => {
|
|
693
|
+
a.url.endsWith("/") || !a.updatedAt || a.url in this.documentsModifiedAt || (this.documentsModifiedAt[a.url] = a.updatedAt);
|
|
694
|
+
},
|
|
695
|
+
onDocumentsLoaded: async () => {
|
|
696
|
+
this.assertNotCancelled(), await this.updateProgress();
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
for (let a = 0; a < n.length; a++) {
|
|
700
|
+
const r = n[a];
|
|
701
|
+
if (r instanceof W) {
|
|
702
|
+
this.tombstones.add(r);
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
705
|
+
if (this.tombstones.hasKey(r.url)) {
|
|
706
|
+
await this.deleteChild(e, r);
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
await this.loadChildren(r, (i = t == null ? void 0 : t.children) == null ? void 0 : i[a]), (l = t == null ? void 0 : t.children) != null && l[a] && await this.updateProgress(() => {
|
|
710
|
+
var c;
|
|
711
|
+
return U((c = t.children) == null ? void 0 : c[a]).completed = !0;
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
async deleteChild(e, t) {
|
|
716
|
+
for (const n of e.static("relations")) {
|
|
717
|
+
const i = e.requireRelation(n);
|
|
718
|
+
if (i.related) {
|
|
719
|
+
if (Array.isArray(i.related)) {
|
|
720
|
+
i.related = i.related.filter((l) => l !== t);
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
if (i.related === t) {
|
|
724
|
+
i.related = null;
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
await t.forceDelete();
|
|
730
|
+
}
|
|
731
|
+
async saveModelAndChildren(e, t) {
|
|
732
|
+
if (this.assertNotCancelled(), Q(e) && e.isSoftDeleted()) {
|
|
733
|
+
e.enableHistory(), e.enableTombstone(), await e.forceDelete();
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
if (this.documentsWithErrors.has(e.requireDocumentUrl()))
|
|
737
|
+
return;
|
|
738
|
+
const n = e.isDirty();
|
|
739
|
+
if (await e.save(), (n || Q(e)) && this.syncedModelUrls.add(e.url), !L(e)) {
|
|
740
|
+
if (Q(e)) {
|
|
741
|
+
const a = e.requireDocumentUrl(), r = this.documentsModifiedAt[a];
|
|
742
|
+
r && (await P.remember(a, r), delete this.documentsModifiedAt[a]);
|
|
743
|
+
}
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
const i = k(e.static()).map((a) => e.getRelationModels(a) ?? []).flat(), l = t ? i.map(() => ({ completed: !1 })) : [];
|
|
747
|
+
t && (t.children = l);
|
|
748
|
+
for (let a = 0; a < i.length; a++) {
|
|
749
|
+
const r = i[a], c = l[a];
|
|
750
|
+
await this.saveModelAndChildren(r, c), c && await this.updateProgress(() => c.completed = !0);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
async synchronizeModels(e) {
|
|
754
|
+
const t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set();
|
|
755
|
+
for (const l of e.items()) {
|
|
756
|
+
if (l instanceof W) {
|
|
757
|
+
const r = this.localModels.get(l.resourceUrl);
|
|
758
|
+
r && (await r.forceDelete(), n.add(r));
|
|
759
|
+
continue;
|
|
760
|
+
}
|
|
761
|
+
const a = Ft(l, this.localModels);
|
|
762
|
+
a.exists() || this.syncedModelUrls.add(a.url), await this.loadChildren(a), await N.synchronize(a, l), await this.reconcileInconsistencies(a, l), await this.saveModelAndChildren(a), await this.addLocalModel(a), this.rootLocalModels.push(a), t.add(a.url);
|
|
763
|
+
}
|
|
764
|
+
for (const l of this.rootLocalModels) {
|
|
765
|
+
if (n.has(l) || t.has(l.url))
|
|
766
|
+
continue;
|
|
767
|
+
await this.loadChildren(l);
|
|
768
|
+
const a = Yt(l, e);
|
|
769
|
+
await N.synchronize(l, a), e.add(a);
|
|
770
|
+
}
|
|
771
|
+
const i = [];
|
|
772
|
+
for (const l of e.getItems()) {
|
|
773
|
+
if (Ne(l)) {
|
|
774
|
+
i.push(l);
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
await this.rememberModelDocuments(l);
|
|
778
|
+
}
|
|
779
|
+
return i;
|
|
780
|
+
}
|
|
781
|
+
async reconcileInconsistencies(e, t, n) {
|
|
782
|
+
e.rebuildAttributesFromHistory(), e.setAttributes(t.getAttributes(!0)), n ?? (n = /* @__PURE__ */ new Set()), n.add(e);
|
|
783
|
+
for (const l of k(e.static()))
|
|
784
|
+
await this.synchronizeContainerDocuments(
|
|
785
|
+
e.requireRelation(l),
|
|
786
|
+
t.requireRelation(l)
|
|
787
|
+
);
|
|
788
|
+
const i = z(fe(t), "url");
|
|
789
|
+
for (const l of fe(e))
|
|
790
|
+
n.has(l) || !l.isRelationLoaded("operations") || !i.hasKey(l.url) || await this.reconcileInconsistencies(
|
|
791
|
+
l,
|
|
792
|
+
i.require(l.url),
|
|
793
|
+
n
|
|
794
|
+
);
|
|
795
|
+
e.isDirty() && (await e.save(), await N.synchronize(e, t));
|
|
796
|
+
}
|
|
797
|
+
async synchronizeContainerDocuments(e, t) {
|
|
798
|
+
const n = z(e.related ?? [], "url"), i = z(t.related ?? [], "url"), l = n.getKeys().filter((r) => !i.hasKey(r) && !i.hasKey(encodeURI(r))), a = i.getKeys().filter((r) => !n.hasKey(r) && !n.hasKey(encodeURI(r)));
|
|
799
|
+
for (const r of l) {
|
|
800
|
+
const c = n.require(r), p = Ce(c);
|
|
801
|
+
t.addRelated(p), i.add(p);
|
|
802
|
+
}
|
|
803
|
+
for (const r of a) {
|
|
804
|
+
const c = i.require(r), p = je(c);
|
|
805
|
+
e.addRelated(p), n.add(p), this.syncedModelUrls.add(p.url);
|
|
806
|
+
}
|
|
807
|
+
for (const r of n.items()) {
|
|
808
|
+
const c = i.require(r.url);
|
|
809
|
+
await N.synchronize(r, c), await this.saveModelAndChildren(r);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
async rememberModelDocuments(e) {
|
|
813
|
+
if (!L(e)) {
|
|
814
|
+
const n = e.requireDocumentUrl(), i = this.documentsModifiedAt[n];
|
|
815
|
+
i && (await P.remember(n, i), delete this.documentsModifiedAt[n]);
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
const t = k(e.static()).map((n) => e.getRelationModels(n) ?? []).flat();
|
|
819
|
+
for (const n of t)
|
|
820
|
+
await this.rememberModelDocuments(n);
|
|
821
|
+
}
|
|
822
|
+
async ignoringDocumentErrors(e) {
|
|
823
|
+
try {
|
|
824
|
+
await e();
|
|
825
|
+
} catch (t) {
|
|
826
|
+
this.handleDocumentError(t);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
handleDocumentError(e) {
|
|
830
|
+
if (E(e, xt)) {
|
|
831
|
+
console.warn(e.message), e.documentUrl && this.documentsWithErrors.add(e.documentUrl);
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
if (E(e, Pt)) {
|
|
835
|
+
console.warn(e.message);
|
|
836
|
+
const t = e.attributes[_t(e.modelName).primaryKey], n = t && qe(wt(t));
|
|
837
|
+
n && this.documentsWithErrors.add(n);
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
throw e;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
const v = {
|
|
844
|
+
Disconnected: "disconnected",
|
|
845
|
+
Online: "online",
|
|
846
|
+
Syncing: "syncing",
|
|
847
|
+
Migrating: "migrating"
|
|
848
|
+
}, cn = et({
|
|
849
|
+
name: "cloud",
|
|
850
|
+
persist: [
|
|
851
|
+
"localModelUpdates",
|
|
852
|
+
"migrationDismissed",
|
|
853
|
+
"migrationJob",
|
|
854
|
+
"modelCollections",
|
|
855
|
+
"pollingEnabled",
|
|
856
|
+
"pollingMinutes",
|
|
857
|
+
"ready",
|
|
858
|
+
"startupSync"
|
|
859
|
+
],
|
|
860
|
+
initialState: () => ({
|
|
861
|
+
autoPush: !0,
|
|
862
|
+
localModelUpdates: {},
|
|
863
|
+
migrationDismissed: !1,
|
|
864
|
+
migrationJob: null,
|
|
865
|
+
migrationPostponed: !1,
|
|
866
|
+
modelCollections: {},
|
|
867
|
+
pollingEnabled: !0,
|
|
868
|
+
pollingMinutes: 10,
|
|
869
|
+
ready: !1,
|
|
870
|
+
registeredModels: [],
|
|
871
|
+
schemaMigrations: /* @__PURE__ */ new Map(),
|
|
872
|
+
setupDismissed: !1,
|
|
873
|
+
setupOngoing: !1,
|
|
874
|
+
startupSync: !0,
|
|
875
|
+
status: v.Disconnected,
|
|
876
|
+
syncError: null,
|
|
877
|
+
syncJob: null
|
|
878
|
+
}),
|
|
879
|
+
serialize: (o) => {
|
|
880
|
+
var s;
|
|
881
|
+
return ve(o, { migrationJob: (s = o.migrationJob) == null ? void 0 : s.serialize() });
|
|
882
|
+
},
|
|
883
|
+
restore: (o) => ve(o, {
|
|
884
|
+
migrationJob: o.migrationJob && oe.restore(o.migrationJob)
|
|
885
|
+
}),
|
|
886
|
+
watch: {
|
|
887
|
+
migrationJob(o) {
|
|
888
|
+
o == null || o.listeners.add({ onUpdated: () => this.updatePersistedState("migrationJob") });
|
|
889
|
+
}
|
|
890
|
+
},
|
|
891
|
+
computed: {
|
|
892
|
+
disconnected: ({ status: o }) => o === v.Disconnected,
|
|
893
|
+
online: ({ status: o }) => o === v.Online,
|
|
894
|
+
syncing: ({ status: o }) => o === v.Syncing,
|
|
895
|
+
migrating: ({ status: o }) => o === v.Migrating,
|
|
896
|
+
localChanges({ localModelUpdates: o }) {
|
|
897
|
+
return Object.values(o).reduce((s, e) => s + e, 0);
|
|
898
|
+
},
|
|
899
|
+
dirty() {
|
|
900
|
+
return this.localChanges > 0;
|
|
901
|
+
},
|
|
902
|
+
migrationStarted({ migrationJob: o }) {
|
|
903
|
+
return !!o;
|
|
904
|
+
},
|
|
905
|
+
migrationDisabledReason({ status: o, ready: s }) {
|
|
906
|
+
return C.isLoggedIn() ? s ? o === v.Syncing || o === v.Migrating ? $(
|
|
907
|
+
"cloud.migrationNotSyncing",
|
|
908
|
+
"Wait for syncing to finish before starting the migration"
|
|
909
|
+
) : this.online ? null : $(
|
|
910
|
+
"cloud.migrationNotOnline",
|
|
911
|
+
"You need to be online in order to start the migration"
|
|
912
|
+
) : $(
|
|
913
|
+
"cloud.migrationNotReady",
|
|
914
|
+
"You need to backup your data before starting the migration"
|
|
915
|
+
) : $(
|
|
916
|
+
"cloud.migrationNotLoggedIn",
|
|
917
|
+
"You need to reconnect before starting the migration"
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
});
|
|
922
|
+
class dn extends cn {
|
|
923
|
+
constructor() {
|
|
924
|
+
super(...arguments);
|
|
925
|
+
w(this, "asyncLock", new Mt());
|
|
926
|
+
w(this, "engine", null);
|
|
927
|
+
w(this, "pollingInterval", null);
|
|
928
|
+
}
|
|
929
|
+
async whenReady(e) {
|
|
930
|
+
return this.ready ? e() : new Promise((t) => {
|
|
931
|
+
const n = () => t(e());
|
|
932
|
+
D.once("cloud:ready", n);
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
async setup(e) {
|
|
936
|
+
this.setupOngoing = !0;
|
|
937
|
+
try {
|
|
938
|
+
await this.backup(e), await this.setReady(!0), await this.sync();
|
|
939
|
+
} finally {
|
|
940
|
+
this.setupOngoing = !1;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
dismissSetup() {
|
|
944
|
+
this.setupDismissed = !0;
|
|
945
|
+
}
|
|
946
|
+
dismissMigration() {
|
|
947
|
+
this.migrationDismissed = !0;
|
|
948
|
+
}
|
|
949
|
+
postponeMigration() {
|
|
950
|
+
this.migrationPostponed = !0;
|
|
951
|
+
}
|
|
952
|
+
async syncIfOnline(e = {}) {
|
|
953
|
+
this.online && await this.sync(e);
|
|
954
|
+
}
|
|
955
|
+
async sync(e = {}) {
|
|
956
|
+
const t = bt(e) ? { models: e } : e instanceof N ? { model: e } : e;
|
|
957
|
+
!C.isLoggedIn() || !this.ready || !this.online || await this.asyncLock.run(async () => {
|
|
958
|
+
const n = Date.now(), i = t.model ? [t.model] : t.models;
|
|
959
|
+
this.syncError = null, this.status = v.Syncing, ne.clear(i);
|
|
960
|
+
try {
|
|
961
|
+
if (await D.emit("cloud:sync-started", i), t.refreshUserProfile && await C.refreshUserProfile(), this.syncJob = new ln(i), this.syncJob.listeners.add(t), await re(this.syncJob), this.syncJob.cancelled)
|
|
962
|
+
return;
|
|
963
|
+
$e("unit") || await G({ milliseconds: Math.max(500, 1e3 - (Date.now() - n)) }), this.syncJob = null;
|
|
964
|
+
} catch (l) {
|
|
965
|
+
if ($e())
|
|
966
|
+
throw l;
|
|
967
|
+
this.syncJob = null, this.syncError = l, await Z.report(l, $("cloud.syncFailed", "Sync failed"));
|
|
968
|
+
} finally {
|
|
969
|
+
this.status = v.Online, await D.emit("cloud:sync-completed", i);
|
|
970
|
+
}
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
shouldMigrate() {
|
|
974
|
+
return this.schemaMigrations.size > 0;
|
|
975
|
+
}
|
|
976
|
+
async migrate(e) {
|
|
977
|
+
if (!this.online || !C.isLoggedIn() || !this.ready)
|
|
978
|
+
throw new Error("Data cannot be migrated at the moment");
|
|
979
|
+
this.shouldMigrate() && await this.asyncLock.run(async () => {
|
|
980
|
+
var l;
|
|
981
|
+
this.status = v.Migrating, this.migrationJob ?? (this.migrationJob = new oe());
|
|
982
|
+
const t = Date.now(), n = [], i = (l = this.migrationJob).models ?? (l.models = pe());
|
|
983
|
+
ne.clear(i);
|
|
984
|
+
try {
|
|
985
|
+
if (e && n.push(this.migrationJob.listeners.add(e)), await D.emit("cloud:migration-started", i), await re(this.migrationJob), this.migrationJob.cancelled) {
|
|
986
|
+
await D.emit("cloud:migration-cancelled", i);
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
this.migrationJob = null, this.migrationDismissed = !1, this.migrationPostponed = !1, await G({ milliseconds: Math.max(0, 1e3 - (Date.now() - t)) }), await D.emit("cloud:migration-completed", i);
|
|
990
|
+
} catch (a) {
|
|
991
|
+
await Z.report(a, $("cloud.migrationFailed", "Migration failed"));
|
|
992
|
+
} finally {
|
|
993
|
+
this.status = v.Online, n.forEach((a) => a == null ? void 0 : a());
|
|
994
|
+
}
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
async register(e, t = {}) {
|
|
998
|
+
if (this.registeredModels.find((i) => e === i.modelClass))
|
|
999
|
+
return;
|
|
1000
|
+
const n = this.engine;
|
|
1001
|
+
n && Re(e).forEach((i) => I(i).setEngine(n)), this.whenReady(() => {
|
|
1002
|
+
const [i] = this.modelCollections[e.modelName] ?? [];
|
|
1003
|
+
e.useSoftDeletes(!0), e.collection = i ?? de(e, t.path);
|
|
1004
|
+
}), await Lt(e, {
|
|
1005
|
+
created: (i) => this.ready && Le(i),
|
|
1006
|
+
updated: (i) => this.ready && Ue(i),
|
|
1007
|
+
deleted: (i) => this.ready && ge(/* @__PURE__ */ new Set([i.url ?? i.getDeletedPrimaryKey()]))
|
|
1008
|
+
}), x(e) && k(e).forEach((i) => {
|
|
1009
|
+
const l = e.instance().requireRelation(i).relatedClass;
|
|
1010
|
+
l.on("created", (a) => this.ready && Le(a)), l.on("updated", (a) => this.ready && Ue(a)), l.on(
|
|
1011
|
+
"deleted",
|
|
1012
|
+
(a) => this.ready && ge(/* @__PURE__ */ new Set([a.url ?? a.getDeletedPrimaryKey()]))
|
|
1013
|
+
);
|
|
1014
|
+
}), this.registeredModels.push({ modelClass: e, path: t.path });
|
|
1015
|
+
for (const i of this.modelCollections[e.modelName] ?? [])
|
|
1016
|
+
await te(e, i);
|
|
1017
|
+
}
|
|
1018
|
+
registerSchemaMigration(e, t) {
|
|
1019
|
+
this.schemaMigrations.set(e, t);
|
|
1020
|
+
}
|
|
1021
|
+
requireRemoteCollection(e) {
|
|
1022
|
+
for (const t of this.registeredModels)
|
|
1023
|
+
if (e === t.modelClass)
|
|
1024
|
+
return de(t.modelClass, t.path);
|
|
1025
|
+
throw new Error(`Failed resolving remote collection for '${e.modelName}' model`);
|
|
1026
|
+
}
|
|
1027
|
+
async boot() {
|
|
1028
|
+
await C.booted, C.isLoggedIn() && this.login(C.authenticator), D.on("auth:login", ({ authenticator: e }) => this.login(e)), D.on("auth:logout", () => this.logout()), D.once("application-ready", () => this.onApplicationReady()), D.once("application-mounted", () => this.onApplicationMounted()), Ut(() => {
|
|
1029
|
+
if (this.pollingInterval && clearInterval(this.pollingInterval), !this.pollingEnabled || this.migrationJob) {
|
|
1030
|
+
this.pollingInterval = null;
|
|
1031
|
+
return;
|
|
1032
|
+
}
|
|
1033
|
+
this.pollingInterval = setInterval(() => this.sync(), this.pollingMinutes * 60 * 1e3);
|
|
1034
|
+
}), await this.bustDocumentsCache(), await this.registerModels();
|
|
1035
|
+
}
|
|
1036
|
+
getDirtyLocalModels() {
|
|
1037
|
+
const e = Object.keys(this.localModelUpdates), t = [];
|
|
1038
|
+
for (const { modelClass: n } of this.registeredModels)
|
|
1039
|
+
for (const i of Me(n, { includeSoftDeleted: !0 }))
|
|
1040
|
+
t.push(...this.getModelsIn(e, i));
|
|
1041
|
+
return t;
|
|
1042
|
+
}
|
|
1043
|
+
getModelsIn(e, t) {
|
|
1044
|
+
const n = [];
|
|
1045
|
+
return e.includes(t.url) && n.push(t), L(t) && n.push(
|
|
1046
|
+
...Je(t).map((i) => this.getModelsIn(e, i)).flat()
|
|
1047
|
+
), n;
|
|
1048
|
+
}
|
|
1049
|
+
requireEngine() {
|
|
1050
|
+
return this.engine ?? Pe("Could not get required Engine");
|
|
1051
|
+
}
|
|
1052
|
+
async setReady(e) {
|
|
1053
|
+
this.ready || !e || (await D.emit("cloud:ready"), this.ready = !0);
|
|
1054
|
+
}
|
|
1055
|
+
async backup(e) {
|
|
1056
|
+
await D.emit("cloud:backup-started"), e ?? (e = /* @__PURE__ */ new WeakMap());
|
|
1057
|
+
const t = new tn();
|
|
1058
|
+
for (const { modelClass: n, path: i } of this.registeredModels) {
|
|
1059
|
+
if (!x(n))
|
|
1060
|
+
continue;
|
|
1061
|
+
for (const [r, c] of Object.entries(e.get(n) ?? {}))
|
|
1062
|
+
t.migrateUrl(n, r, c);
|
|
1063
|
+
const l = n.collection, a = de(n, i);
|
|
1064
|
+
n.collection = a, t.migrateCollection(n, l, a);
|
|
1065
|
+
}
|
|
1066
|
+
await re(t), await D.emit("cloud:backup-completed");
|
|
1067
|
+
}
|
|
1068
|
+
async onApplicationReady() {
|
|
1069
|
+
this.ready || !C.isLoggedIn() || await this.setReady(!pe().some((e) => e.url.startsWith("solid://")));
|
|
1070
|
+
}
|
|
1071
|
+
async onApplicationMounted() {
|
|
1072
|
+
this.syncOnStartup() && await this.sync();
|
|
1073
|
+
}
|
|
1074
|
+
login(e) {
|
|
1075
|
+
const t = [...this.registeredModels].map(({ modelClass: n }) => Re(n)).flat().concat([W]);
|
|
1076
|
+
this.status = v.Online, this.engine = e.engine, I(j).setEngine(this.engine);
|
|
1077
|
+
for (const n of t)
|
|
1078
|
+
I(n).setEngine(this.engine);
|
|
1079
|
+
}
|
|
1080
|
+
logout() {
|
|
1081
|
+
this.setState({
|
|
1082
|
+
localModelUpdates: {},
|
|
1083
|
+
migrationDismissed: !1,
|
|
1084
|
+
migrationJob: null,
|
|
1085
|
+
migrationPostponed: !1,
|
|
1086
|
+
modelCollections: {},
|
|
1087
|
+
pollingEnabled: !0,
|
|
1088
|
+
pollingMinutes: 10,
|
|
1089
|
+
ready: !1,
|
|
1090
|
+
setupDismissed: !1,
|
|
1091
|
+
setupOngoing: !1,
|
|
1092
|
+
startupSync: !0,
|
|
1093
|
+
status: v.Disconnected
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
syncOnStartup() {
|
|
1097
|
+
return Se("startupSync") ? De(ke("startupSync")) : this.migrationJob ? !1 : this.startupSync;
|
|
1098
|
+
}
|
|
1099
|
+
async bustDocumentsCache() {
|
|
1100
|
+
!Se("bustDocumentsCache") || !De(ke("bustDocumentsCache")) || (await P.booted, await P.clear());
|
|
1101
|
+
}
|
|
1102
|
+
async registerModels() {
|
|
1103
|
+
const e = Ot();
|
|
1104
|
+
for (const t of e.values())
|
|
1105
|
+
!kt(t) || !t.cloud || await this.register(t, typeof t.cloud == "boolean" ? {} : t.cloud);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
const A = we(dn), un = {
|
|
1109
|
+
viewBox: "0 0 20 20",
|
|
1110
|
+
width: "1.2em",
|
|
1111
|
+
height: "1.2em"
|
|
1112
|
+
};
|
|
1113
|
+
function hn(o, s) {
|
|
1114
|
+
return h(), M("svg", un, s[0] || (s[0] = [
|
|
1115
|
+
f("path", {
|
|
1116
|
+
fill: "currentColor",
|
|
1117
|
+
d: "m6 2l2-2h4l2 2h4v2H2V2zM3 6h14l-1 14H4zm5 2v10h1V8zm3 0v10h1V8z"
|
|
1118
|
+
}, null, -1)
|
|
1119
|
+
]));
|
|
1120
|
+
}
|
|
1121
|
+
const fn = _({ name: "zondicons-trash", render: hn }), He = /* @__PURE__ */ B({
|
|
1122
|
+
__name: "AccountLoginModal",
|
|
1123
|
+
setup(o) {
|
|
1124
|
+
return (s, e) => (h(), R(d(ze), {
|
|
1125
|
+
title: s.$td("cloud.logIn.title", "Connect account")
|
|
1126
|
+
}, {
|
|
1127
|
+
default: b(() => [
|
|
1128
|
+
u(d(T), {
|
|
1129
|
+
"lang-key": "cloud.logIn.info",
|
|
1130
|
+
"lang-default": "Log in to your [Solid account](https://solidproject.org) to keep data safe across devices."
|
|
1131
|
+
}),
|
|
1132
|
+
u(d(ue), {
|
|
1133
|
+
class: "mt-2 text-sm opacity-50 hover:opacity-75 focus-visible:opacity-75",
|
|
1134
|
+
onClick: e[0] || (e[0] = (t) => s.$ui.alert(
|
|
1135
|
+
s.$td("cloud.logIn.learnMore", "What is Solid?"),
|
|
1136
|
+
s.$td(
|
|
1137
|
+
"cloud.logIn.learnMoreMessage",
|
|
1138
|
+
`Solid is a decentralized storage protocol built on top of web standards. If you want to use this app across devices, you can use Solid to keep changes in sync. Even if you use it in a single device, this will also keep your data secure in case your device is lost.
|
|
1139
|
+
|
|
1140
|
+
In any case, Focus works 100% offline and you can connect your Solid POD later on. If you've never heard of Solid and you're just trying things out, you can keep using it without an account.
|
|
1141
|
+
|
|
1142
|
+
[Learn more](https://solidproject.org)`
|
|
1143
|
+
)
|
|
1144
|
+
))
|
|
1145
|
+
}, {
|
|
1146
|
+
default: b(() => [
|
|
1147
|
+
K(S(s.$td("cloud.logIn.learnMore", "What is Solid?")), 1)
|
|
1148
|
+
]),
|
|
1149
|
+
_: 1
|
|
1150
|
+
}),
|
|
1151
|
+
u(d(Ct), {
|
|
1152
|
+
"no-loading": "",
|
|
1153
|
+
class: "mt-4"
|
|
1154
|
+
})
|
|
1155
|
+
]),
|
|
1156
|
+
_: 1
|
|
1157
|
+
}, 8, ["title"]));
|
|
1158
|
+
}
|
|
1159
|
+
}), mn = {
|
|
1160
|
+
key: 0,
|
|
1161
|
+
class: "mt-4"
|
|
1162
|
+
}, gn = { class: "text-base font-semibold" }, pn = { class: "ml-1" }, yn = /* @__PURE__ */ B({
|
|
1163
|
+
__name: "PurgeData",
|
|
1164
|
+
setup(o) {
|
|
1165
|
+
async function s() {
|
|
1166
|
+
await ae.confirm(
|
|
1167
|
+
$("settings.purgeConfirmTitle", "Delete everything?"),
|
|
1168
|
+
$(
|
|
1169
|
+
"settings.purgeConfirmMessage",
|
|
1170
|
+
"If you proceed, all your data will be deleted forever. If you want to save it before wiping this device, you can [connect to your Solid account](#action:connect) first."
|
|
1171
|
+
),
|
|
1172
|
+
{
|
|
1173
|
+
acceptVariant: "danger",
|
|
1174
|
+
acceptText: $("settings.purgeConfirmAccept", "Purge data"),
|
|
1175
|
+
actions: { connect: () => ae.modal(He) }
|
|
1176
|
+
}
|
|
1177
|
+
) && (await ae.closeAllModals(), await tt.purge());
|
|
1178
|
+
}
|
|
1179
|
+
return (e, t) => e.$solid.hasLoggedIn() ? O("", !0) : (h(), M("details", mn, [
|
|
1180
|
+
f("summary", null, [
|
|
1181
|
+
f("span", gn, S(e.$td("settings.dangerZone", "Danger zone")), 1)
|
|
1182
|
+
]),
|
|
1183
|
+
u(d(q), {
|
|
1184
|
+
variant: "danger",
|
|
1185
|
+
class: "mt-4",
|
|
1186
|
+
onClick: t[0] || (t[0] = (n) => s())
|
|
1187
|
+
}, {
|
|
1188
|
+
default: b(() => [
|
|
1189
|
+
u(d(fn), { class: "size-4" }),
|
|
1190
|
+
f("span", pn, S(e.$td("settings.purge", "Purge data")), 1)
|
|
1191
|
+
]),
|
|
1192
|
+
_: 1
|
|
1193
|
+
})
|
|
1194
|
+
]));
|
|
1195
|
+
}
|
|
1196
|
+
}), wn = nt([
|
|
1197
|
+
{
|
|
1198
|
+
priority: 0,
|
|
1199
|
+
component: yn
|
|
1200
|
+
}
|
|
1201
|
+
]), Mn = {
|
|
1202
|
+
viewBox: "0 0 20 20",
|
|
1203
|
+
width: "1.2em",
|
|
1204
|
+
height: "1.2em"
|
|
1205
|
+
};
|
|
1206
|
+
function bn(o, s) {
|
|
1207
|
+
return h(), M("svg", Mn, s[0] || (s[0] = [
|
|
1208
|
+
f("path", {
|
|
1209
|
+
fill: "currentColor",
|
|
1210
|
+
d: "M2.93 17.07A10 10 0 1 1 17.07 2.93A10 10 0 0 1 2.93 17.07m12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32M6.7 9.29L9 11.6l4.3-4.3l1.4 1.42L9 14.4l-3.7-3.7l1.4-1.42z"
|
|
1211
|
+
}, null, -1)
|
|
1212
|
+
]));
|
|
1213
|
+
}
|
|
1214
|
+
const Cn = _({ name: "zondicons-checkmark-outline", render: bn }), vn = {
|
|
1215
|
+
viewBox: "0 0 24 24",
|
|
1216
|
+
width: "1.2em",
|
|
1217
|
+
height: "1.2em"
|
|
1218
|
+
};
|
|
1219
|
+
function $n(o, s) {
|
|
1220
|
+
return h(), M("svg", vn, s[0] || (s[0] = [
|
|
1221
|
+
f("path", {
|
|
1222
|
+
fill: "currentColor",
|
|
1223
|
+
d: "M19.35 10.04A7.49 7.49 0 0 0 12 4C9.11 4 6.6 5.64 5.35 8.04A5.994 5.994 0 0 0 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5c0-2.64-2.05-4.78-4.65-4.96M14 13v4h-4v-4H7l5-5l5 5z"
|
|
1224
|
+
}, null, -1)
|
|
1225
|
+
]));
|
|
1226
|
+
}
|
|
1227
|
+
const Sn = _({ name: "ic-sharp-cloud-upload", render: $n }), Dn = {
|
|
1228
|
+
viewBox: "0 0 20 20",
|
|
1229
|
+
width: "1.2em",
|
|
1230
|
+
height: "1.2em"
|
|
1231
|
+
};
|
|
1232
|
+
function kn(o, s) {
|
|
1233
|
+
return h(), M("svg", Dn, s[0] || (s[0] = [
|
|
1234
|
+
f("path", {
|
|
1235
|
+
fill: "currentColor",
|
|
1236
|
+
d: "M3.94 6.5L2.22 3.64l1.42-1.42L6.5 3.94c.52-.3 1.1-.54 1.7-.7L9 0h2l.8 3.24c.6.16 1.18.4 1.7.7l2.86-1.72l1.42 1.42l-1.72 2.86c.3.52.54 1.1.7 1.7L20 9v2l-3.24.8c-.16.6-.4 1.18-.7 1.7l1.72 2.86l-1.42 1.42l-2.86-1.72c-.52.3-1.1.54-1.7.7L11 20H9l-.8-3.24c-.6-.16-1.18-.4-1.7-.7l-2.86 1.72l-1.42-1.42l1.72-2.86c-.3-.52-.54-1.1-.7-1.7L0 11V9l3.24-.8c.16-.6.4-1.18.7-1.7M10 13a3 3 0 1 0 0-6a3 3 0 0 0 0 6"
|
|
1237
|
+
}, null, -1)
|
|
1238
|
+
]));
|
|
1239
|
+
}
|
|
1240
|
+
const Ke = _({ name: "zondicons-cog", render: kn }), Rn = {
|
|
1241
|
+
viewBox: "0 0 24 24",
|
|
1242
|
+
width: "1.2em",
|
|
1243
|
+
height: "1.2em"
|
|
1244
|
+
};
|
|
1245
|
+
function Ln(o, s) {
|
|
1246
|
+
return h(), M("svg", Rn, s[0] || (s[0] = [
|
|
1247
|
+
f("path", {
|
|
1248
|
+
fill: "currentColor",
|
|
1249
|
+
d: "M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h6q.425 0 .713.288T12 4t-.288.713T11 5H5v14h6q.425 0 .713.288T12 20t-.288.713T11 21zm12.175-8H10q-.425 0-.712-.288T9 12t.288-.712T10 11h7.175L15.3 9.125q-.275-.275-.275-.675t.275-.7t.7-.313t.725.288L20.3 11.3q.3.3.3.7t-.3.7l-3.575 3.575q-.3.3-.712.288t-.713-.313q-.275-.3-.262-.712t.287-.688z"
|
|
1250
|
+
}, null, -1)
|
|
1251
|
+
]));
|
|
1252
|
+
}
|
|
1253
|
+
const Un = _({ name: "material-symbols-logout-rounded", render: Ln }), An = {
|
|
1254
|
+
viewBox: "0 0 20 20",
|
|
1255
|
+
width: "1.2em",
|
|
1256
|
+
height: "1.2em"
|
|
1257
|
+
};
|
|
1258
|
+
function In(o, s) {
|
|
1259
|
+
return h(), M("svg", An, s[0] || (s[0] = [
|
|
1260
|
+
f("path", {
|
|
1261
|
+
fill: "currentColor",
|
|
1262
|
+
d: "M10 3v2a5 5 0 0 0-3.54 8.54l-1.41 1.41A7 7 0 0 1 10 3m4.95 2.05A7 7 0 0 1 10 17v-2a5 5 0 0 0 3.54-8.54zM10 20l-4-4l4-4zm0-12V0l4 4z"
|
|
1263
|
+
}, null, -1)
|
|
1264
|
+
]));
|
|
1265
|
+
}
|
|
1266
|
+
const F = _({ name: "zondicons-refresh", render: In }), zn = {
|
|
1267
|
+
viewBox: "0 0 24 24",
|
|
1268
|
+
width: "1.2em",
|
|
1269
|
+
height: "1.2em"
|
|
1270
|
+
};
|
|
1271
|
+
function En(o, s) {
|
|
1272
|
+
return h(), M("svg", zn, s[0] || (s[0] = [
|
|
1273
|
+
f("path", {
|
|
1274
|
+
fill: "currentColor",
|
|
1275
|
+
d: "M6 6h12v12H6z"
|
|
1276
|
+
}, null, -1)
|
|
1277
|
+
]));
|
|
1278
|
+
}
|
|
1279
|
+
const Tn = _({ name: "ic-baseline-stop", render: En }), qn = {
|
|
1280
|
+
viewBox: "0 0 512 512",
|
|
1281
|
+
width: "1.2em",
|
|
1282
|
+
height: "1.2em"
|
|
1283
|
+
};
|
|
1284
|
+
function Pn(o, s) {
|
|
1285
|
+
return h(), M("svg", qn, s[0] || (s[0] = [
|
|
1286
|
+
f("path", {
|
|
1287
|
+
fill: "currentColor",
|
|
1288
|
+
d: "M449.07 399.08L278.64 82.58c-12.08-22.44-44.26-22.44-56.35 0L51.87 399.08A32 32 0 0 0 80 446.25h340.89a32 32 0 0 0 28.18-47.17m-198.6-1.83a20 20 0 1 1 20-20a20 20 0 0 1-20 20m21.72-201.15l-5.74 122a16 16 0 0 1-32 0l-5.74-121.95a21.73 21.73 0 0 1 21.5-22.69h.21a21.74 21.74 0 0 1 21.73 22.7Z"
|
|
1289
|
+
}, null, -1)
|
|
1290
|
+
]));
|
|
1291
|
+
}
|
|
1292
|
+
const H = _({ name: "ion-warning", render: Pn }), _n = { class: "relative flex items-center rounded-md bg-gray-100 p-4 pr-12" }, On = { class: "flex flex-col overflow-hidden" }, xn = { class: "font-semibold" }, Jn = { class: "px-2" }, Nn = {
|
|
1293
|
+
key: 0,
|
|
1294
|
+
class: "mt-4 flex items-center gap-2"
|
|
1295
|
+
}, Wn = { class: "flex w-full flex-col" }, jn = {
|
|
1296
|
+
key: 1,
|
|
1297
|
+
class: "mt-4 flex items-center gap-2"
|
|
1298
|
+
}, Bn = {
|
|
1299
|
+
key: 2,
|
|
1300
|
+
class: "mt-4 flex items-center gap-2"
|
|
1301
|
+
}, Vn = {
|
|
1302
|
+
key: 3,
|
|
1303
|
+
class: "mt-4 flex items-center gap-2"
|
|
1304
|
+
}, Fn = {
|
|
1305
|
+
key: 4,
|
|
1306
|
+
class: "mt-4 flex items-center gap-2"
|
|
1307
|
+
}, Hn = {
|
|
1308
|
+
key: 5,
|
|
1309
|
+
class: "mt-4 flex items-center gap-2"
|
|
1310
|
+
}, Kn = {
|
|
1311
|
+
key: 6,
|
|
1312
|
+
class: "mt-4 flex items-center gap-2"
|
|
1313
|
+
}, Yn = { class: "flex flex-col gap-2" }, Qn = { class: "flex items-center" }, Zn = { "aria-hidden": "true" }, Gn = {
|
|
1314
|
+
key: 0,
|
|
1315
|
+
"aria-hidden": "true"
|
|
1316
|
+
}, Xn = {
|
|
1317
|
+
key: 0,
|
|
1318
|
+
class: "mt-4 flex flex-row-reverse justify-start gap-2"
|
|
1319
|
+
}, es = /* @__PURE__ */ B({
|
|
1320
|
+
__name: "AccountModal",
|
|
1321
|
+
setup(o) {
|
|
1322
|
+
const s = At("$modalRef"), e = It(!1), t = $("cloud.advanced.polling", "Synchronize every {minutes} minutes", {
|
|
1323
|
+
minutes: "%%separator%%"
|
|
1324
|
+
}).split("%%separator%%"), n = Y(() => C.error ?? A.syncError), i = Y(() => {
|
|
1325
|
+
if (n.value)
|
|
1326
|
+
return typeof n.value == "string" ? n.value : $("cloud.info.error", "There has been an error connecting.");
|
|
1327
|
+
}), l = Y(() => n.value && typeof n.value != "string");
|
|
1328
|
+
async function a() {
|
|
1329
|
+
A.syncJob && (e.value = !0, await Promise.race([A.syncJob.cancel(), A.syncJob.completed]), e.value = !1);
|
|
1330
|
+
}
|
|
1331
|
+
return st("auth:logout", () => {
|
|
1332
|
+
var r;
|
|
1333
|
+
return (r = s.value) == null ? void 0 : r.close();
|
|
1334
|
+
}), (r, c) => (h(), R(d(ze), {
|
|
1335
|
+
ref: "$modalRef",
|
|
1336
|
+
"title-hidden": "",
|
|
1337
|
+
"close-hidden": "",
|
|
1338
|
+
title: r.$td("account.title", "Account")
|
|
1339
|
+
}, {
|
|
1340
|
+
default: b(() => {
|
|
1341
|
+
var p, m;
|
|
1342
|
+
return [
|
|
1343
|
+
f("div", _n, [
|
|
1344
|
+
u(d(Oe), { class: "mr-2 size-16 shrink-0" }),
|
|
1345
|
+
f("div", On, [
|
|
1346
|
+
f("span", xn, S(((p = r.$solid.user) == null ? void 0 : p.name) ?? r.$td("user.anonymous", "Anonymous")), 1),
|
|
1347
|
+
u(d(ue), {
|
|
1348
|
+
href: (m = r.$solid.user) == null ? void 0 : m.webId,
|
|
1349
|
+
class: "mt-0.5 truncate text-sm font-light text-gray-500"
|
|
1350
|
+
}, {
|
|
1351
|
+
default: b(() => {
|
|
1352
|
+
var g;
|
|
1353
|
+
return [
|
|
1354
|
+
K(S((g = r.$solid.user) == null ? void 0 : g.webId), 1)
|
|
1355
|
+
];
|
|
1356
|
+
}),
|
|
1357
|
+
_: 1
|
|
1358
|
+
}, 8, ["href"])
|
|
1359
|
+
]),
|
|
1360
|
+
u(d(q), {
|
|
1361
|
+
size: "icon",
|
|
1362
|
+
variant: "ghost",
|
|
1363
|
+
class: "absolute top-1 right-1 hover:bg-gray-200",
|
|
1364
|
+
"aria-label": r.$td("user.settings", "Settings"),
|
|
1365
|
+
title: r.$td("user.settings", "Settings"),
|
|
1366
|
+
onClick: c[0] || (c[0] = (g) => r.$ui.modal(d(Ee)))
|
|
1367
|
+
}, {
|
|
1368
|
+
default: b(() => [
|
|
1369
|
+
u(d(Ke), { class: "size-5" })
|
|
1370
|
+
]),
|
|
1371
|
+
_: 1
|
|
1372
|
+
}, 8, ["aria-label", "title"])
|
|
1373
|
+
]),
|
|
1374
|
+
f("div", Jn, [
|
|
1375
|
+
r.$cloud.syncing ? (h(), M("div", Nn, [
|
|
1376
|
+
u(d(F), { class: "mt-0.5 size-6 shrink-0 animate-spin self-start text-green-500" }),
|
|
1377
|
+
f("div", Wn, [
|
|
1378
|
+
u(d(T), {
|
|
1379
|
+
"lang-key": "cloud.info.syncing",
|
|
1380
|
+
"lang-default": "Synchronizing..."
|
|
1381
|
+
}),
|
|
1382
|
+
r.$cloud.syncJob ? (h(), R(d(ot), {
|
|
1383
|
+
key: 0,
|
|
1384
|
+
job: r.$cloud.syncJob,
|
|
1385
|
+
"filled-class": "bg-green-500"
|
|
1386
|
+
}, null, 8, ["job"])) : O("", !0)
|
|
1387
|
+
])
|
|
1388
|
+
])) : r.$solid.loginOngoing ? (h(), M("div", jn, [
|
|
1389
|
+
u(d(F), { class: "mt-0.5 size-6 shrink-0 animate-spin self-start text-green-500" }),
|
|
1390
|
+
u(d(T), {
|
|
1391
|
+
"lang-key": "cloud.info.reconnecting",
|
|
1392
|
+
"lang-default": "Reconnecting..."
|
|
1393
|
+
})
|
|
1394
|
+
])) : n.value ? (h(), M("div", Bn, [
|
|
1395
|
+
u(d(H), { class: "mt-0.5 size-6 shrink-0 self-start text-red-500" }),
|
|
1396
|
+
f("div", null, [
|
|
1397
|
+
u(d(T), { text: i.value }, null, 8, ["text"]),
|
|
1398
|
+
l.value ? (h(), R(d(ue), {
|
|
1399
|
+
key: 0,
|
|
1400
|
+
class: "text-sm text-red-700 opacity-50 hover:opacity-75 focus-visible:opacity-75",
|
|
1401
|
+
onClick: c[1] || (c[1] = (g) => r.$errors.inspect(n.value))
|
|
1402
|
+
}, {
|
|
1403
|
+
default: b(() => [
|
|
1404
|
+
K(S(r.$td("errors.viewDetails", "View details")), 1)
|
|
1405
|
+
]),
|
|
1406
|
+
_: 1
|
|
1407
|
+
})) : O("", !0)
|
|
1408
|
+
])
|
|
1409
|
+
])) : r.$cloud.ready ? r.$cloud.dirty ? (h(), M("div", Fn, [
|
|
1410
|
+
u(d(H), { class: "mt-0.5 size-6 shrink-0 self-start text-yellow-500" }),
|
|
1411
|
+
u(d(T), {
|
|
1412
|
+
"lang-key": "cloud.info.changes",
|
|
1413
|
+
"lang-default": "Everything is up to date. | There is one local change. | There are {n} local changes.",
|
|
1414
|
+
"lang-params": r.$cloud.localChanges
|
|
1415
|
+
}, null, 8, ["lang-params"])
|
|
1416
|
+
])) : r.$cloud.online ? (h(), M("div", Hn, [
|
|
1417
|
+
u(d(Cn), { class: "mt-0.5 size-6 shrink-0 self-start text-green-500" }),
|
|
1418
|
+
u(d(T), {
|
|
1419
|
+
"lang-key": "cloud.info.changes",
|
|
1420
|
+
"lang-default": "Everything is up to date.",
|
|
1421
|
+
"lang-params": 0
|
|
1422
|
+
})
|
|
1423
|
+
])) : (h(), M("div", Kn, [
|
|
1424
|
+
u(d(H), { class: "mt-0.5 size-6 shrink-0 self-start text-yellow-500" }),
|
|
1425
|
+
u(d(T), {
|
|
1426
|
+
"lang-key": "cloud.info.disconnected",
|
|
1427
|
+
"lang-default": "You are disconnected from your Solid account, all the changes you make will remain in your device."
|
|
1428
|
+
})
|
|
1429
|
+
])) : (h(), M("div", Vn, [
|
|
1430
|
+
u(d(H), { class: "mt-0.5 size-6 shrink-0 self-start text-yellow-500" }),
|
|
1431
|
+
u(d(T), {
|
|
1432
|
+
"lang-key": "cloud.info.setup",
|
|
1433
|
+
"lang-default": "Your data is not backed up yet."
|
|
1434
|
+
})
|
|
1435
|
+
])),
|
|
1436
|
+
u(d(it), { class: "mt-2" }, {
|
|
1437
|
+
default: b(() => [
|
|
1438
|
+
f("ul", Yn, [
|
|
1439
|
+
f("li", null, [
|
|
1440
|
+
u(d(le), {
|
|
1441
|
+
modelValue: r.$solid.autoReconnect,
|
|
1442
|
+
"onUpdate:modelValue": c[2] || (c[2] = (g) => r.$solid.autoReconnect = g),
|
|
1443
|
+
"label-class": "text-base",
|
|
1444
|
+
label: r.$td("cloud.advanced.reconnect", "Reconnect on startup")
|
|
1445
|
+
}, null, 8, ["modelValue", "label"])
|
|
1446
|
+
]),
|
|
1447
|
+
f("li", null, [
|
|
1448
|
+
u(d(le), {
|
|
1449
|
+
modelValue: r.$cloud.startupSync,
|
|
1450
|
+
"onUpdate:modelValue": c[3] || (c[3] = (g) => r.$cloud.startupSync = g),
|
|
1451
|
+
"label-class": "text-base",
|
|
1452
|
+
label: r.$td("cloud.advanced.startupSync", "Synchronize on startup")
|
|
1453
|
+
}, null, 8, ["modelValue", "label"])
|
|
1454
|
+
]),
|
|
1455
|
+
f("li", null, [
|
|
1456
|
+
u(d(le), {
|
|
1457
|
+
modelValue: r.$cloud.pollingEnabled,
|
|
1458
|
+
"onUpdate:modelValue": c[5] || (c[5] = (g) => r.$cloud.pollingEnabled = g),
|
|
1459
|
+
"label-class": "text-base"
|
|
1460
|
+
}, {
|
|
1461
|
+
default: b(() => [
|
|
1462
|
+
f("div", Qn, [
|
|
1463
|
+
f("span", Zn, S(d(t)[0]), 1),
|
|
1464
|
+
u(d(rt), {
|
|
1465
|
+
type: "number",
|
|
1466
|
+
text: `${r.$cloud.pollingMinutes}`,
|
|
1467
|
+
"aria-label": r.$td("cloud.advanced.pollingMinutes", "Synchronization interval (in minutes)"),
|
|
1468
|
+
class: "focus-within:border-primary-600 mx-1 -mb-px border-b",
|
|
1469
|
+
onUpdate: c[4] || (c[4] = (g) => r.$cloud.pollingMinutes = g)
|
|
1470
|
+
}, {
|
|
1471
|
+
default: b(() => [
|
|
1472
|
+
K(S(r.$cloud.pollingMinutes), 1)
|
|
1473
|
+
]),
|
|
1474
|
+
_: 1
|
|
1475
|
+
}, 8, ["text", "aria-label"]),
|
|
1476
|
+
d(t).length > 1 ? (h(), M("span", Gn, S(d(t)[1]), 1)) : O("", !0)
|
|
1477
|
+
])
|
|
1478
|
+
]),
|
|
1479
|
+
_: 1
|
|
1480
|
+
}, 8, ["modelValue"])
|
|
1481
|
+
])
|
|
1482
|
+
])
|
|
1483
|
+
]),
|
|
1484
|
+
_: 1
|
|
1485
|
+
})
|
|
1486
|
+
]),
|
|
1487
|
+
r.$solid.loginOngoing ? O("", !0) : (h(), M("div", Xn, [
|
|
1488
|
+
r.$cloud.syncing ? (h(), R(d(q), {
|
|
1489
|
+
key: 0,
|
|
1490
|
+
variant: "secondary",
|
|
1491
|
+
disabled: e.value,
|
|
1492
|
+
onClick: c[6] || (c[6] = (g) => a())
|
|
1493
|
+
}, {
|
|
1494
|
+
default: b(() => [
|
|
1495
|
+
u(d(Tn), { class: "size-5" }),
|
|
1496
|
+
f("span", null, S(e.value ? r.$td("cloud.stopping", "Stopping...") : r.$td("cloud.stop", "Stop synchronization")), 1)
|
|
1497
|
+
]),
|
|
1498
|
+
_: 1
|
|
1499
|
+
}, 8, ["disabled"])) : r.$solid.isLoggedIn() ? r.$cloud.ready ? (h(), R(d(q), {
|
|
1500
|
+
key: 2,
|
|
1501
|
+
onClick: c[8] || (c[8] = (g) => r.$cloud.sync({ refreshUserProfile: !0 }))
|
|
1502
|
+
}, {
|
|
1503
|
+
default: b(() => [
|
|
1504
|
+
u(d(F), { class: "size-5" }),
|
|
1505
|
+
f("span", null, S(r.$td("cloud.sync", "Synchronize")), 1)
|
|
1506
|
+
]),
|
|
1507
|
+
_: 1
|
|
1508
|
+
})) : (h(), R(d(q), {
|
|
1509
|
+
key: 3,
|
|
1510
|
+
onClick: c[9] || (c[9] = (g) => {
|
|
1511
|
+
var J;
|
|
1512
|
+
return r.$cloud.setupDismissed = !1, (J = d(s)) == null ? void 0 : J.close();
|
|
1513
|
+
})
|
|
1514
|
+
}, {
|
|
1515
|
+
default: b(() => [
|
|
1516
|
+
u(d(Sn), { class: "size-5" }),
|
|
1517
|
+
f("span", null, S(r.$td("cloud.setup.submit", "Back up now")), 1)
|
|
1518
|
+
]),
|
|
1519
|
+
_: 1
|
|
1520
|
+
})) : (h(), R(d(q), {
|
|
1521
|
+
key: 1,
|
|
1522
|
+
onClick: c[7] || (c[7] = (g) => r.$solid.reconnect({ force: !0 }))
|
|
1523
|
+
}, {
|
|
1524
|
+
default: b(() => [
|
|
1525
|
+
u(d(F), { class: "size-5" }),
|
|
1526
|
+
f("span", null, S(r.$td("cloud.reconnect", "Reconnect")), 1)
|
|
1527
|
+
]),
|
|
1528
|
+
_: 1
|
|
1529
|
+
})),
|
|
1530
|
+
r.$cloud.syncing ? O("", !0) : (h(), R(d(q), {
|
|
1531
|
+
key: 4,
|
|
1532
|
+
variant: "secondary",
|
|
1533
|
+
onClick: c[10] || (c[10] = (g) => r.$solid.logout())
|
|
1534
|
+
}, {
|
|
1535
|
+
default: b(() => [
|
|
1536
|
+
u(d(Un), { class: "size-5" }),
|
|
1537
|
+
f("span", null, S(r.$cloud.ready ? r.$td("cloud.logOut", "Log out") : r.$td("cloud.disconnect", "Disconnect")), 1)
|
|
1538
|
+
]),
|
|
1539
|
+
_: 1
|
|
1540
|
+
}))
|
|
1541
|
+
]))
|
|
1542
|
+
];
|
|
1543
|
+
}),
|
|
1544
|
+
_: 1
|
|
1545
|
+
}, 8, ["title"]));
|
|
1546
|
+
}
|
|
1547
|
+
}), ts = { class: "relative size-12" }, ns = ["aria-label", "title"], ss = {
|
|
1548
|
+
key: 0,
|
|
1549
|
+
class: "absolute -inset-1 animate-spin rounded-full border-2 border-[currentColor_transparent] text-green-500"
|
|
1550
|
+
}, os = { class: "sr-only" }, is = /* @__PURE__ */ B({
|
|
1551
|
+
__name: "AccountLoggedIn",
|
|
1552
|
+
setup(o) {
|
|
1553
|
+
const s = Y(() => A.syncing || C.loginOngoing ? {
|
|
1554
|
+
loading: !0,
|
|
1555
|
+
classes: "bg-green-500 sr-only",
|
|
1556
|
+
message: e() ?? ""
|
|
1557
|
+
} : C.error || A.syncError ? {
|
|
1558
|
+
classes: "bg-red-500",
|
|
1559
|
+
message: $("account.error", "There has been an error connecting with your account.")
|
|
1560
|
+
} : !C.isLoggedIn() || A.dirty || !A.ready ? {
|
|
1561
|
+
classes: "bg-yellow-500",
|
|
1562
|
+
message: $(
|
|
1563
|
+
"account.dirty",
|
|
1564
|
+
"There are local changes that haven't been synchronized yet."
|
|
1565
|
+
)
|
|
1566
|
+
} : {
|
|
1567
|
+
classes: "bg-green-500",
|
|
1568
|
+
message: e() ?? ""
|
|
1569
|
+
});
|
|
1570
|
+
function e() {
|
|
1571
|
+
switch (A.status) {
|
|
1572
|
+
case v.Syncing:
|
|
1573
|
+
return $("cloud.status.syncing", "Synchronization in progress");
|
|
1574
|
+
case v.Migrating:
|
|
1575
|
+
return $("cloud.status.migrating", "Migration in progress");
|
|
1576
|
+
case v.Online:
|
|
1577
|
+
return $("cloud.status.online", "Online");
|
|
1578
|
+
case v.Disconnected:
|
|
1579
|
+
return $("cloud.status.disconnected", "Disconnected");
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
return (t, n) => (h(), M("div", ts, [
|
|
1583
|
+
f("button", {
|
|
1584
|
+
class: "clickable focus-visible:outline-primary-600 flex size-full rounded-full focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2",
|
|
1585
|
+
type: "button",
|
|
1586
|
+
"aria-label": t.$td("account.open", "Open account"),
|
|
1587
|
+
title: t.$td("account.open", "Open account"),
|
|
1588
|
+
onClick: n[0] || (n[0] = (i) => t.$ui.modal(es))
|
|
1589
|
+
}, [
|
|
1590
|
+
u(d(Oe), { class: "size-full" }),
|
|
1591
|
+
s.value.loading ? (h(), M("div", ss)) : O("", !0)
|
|
1592
|
+
], 8, ns),
|
|
1593
|
+
f("div", {
|
|
1594
|
+
class: zt(["pointer-events-none absolute right-0 bottom-0 size-3 rounded-full border-2 border-white", s.value.classes])
|
|
1595
|
+
}, [
|
|
1596
|
+
f("span", os, S(s.value.message), 1)
|
|
1597
|
+
], 2)
|
|
1598
|
+
]));
|
|
1599
|
+
}
|
|
1600
|
+
}), rs = /* @__PURE__ */ B({
|
|
1601
|
+
__name: "AccountLoggedOut",
|
|
1602
|
+
setup(o) {
|
|
1603
|
+
return (s, e) => (h(), R(d(at), {
|
|
1604
|
+
align: "start",
|
|
1605
|
+
options: [
|
|
1606
|
+
{ label: s.$td("user.logIn", "Connect account"), click: () => s.$ui.modal(He) },
|
|
1607
|
+
{ label: s.$td("user.settings", "Settings"), click: () => s.$ui.modal(d(Ee)) }
|
|
1608
|
+
]
|
|
1609
|
+
}, {
|
|
1610
|
+
default: b(() => [
|
|
1611
|
+
u(d(q), {
|
|
1612
|
+
size: "icon",
|
|
1613
|
+
variant: "ghost",
|
|
1614
|
+
"aria-label": s.$td("user.menu", "Configuration"),
|
|
1615
|
+
title: s.$td("user.menu", "Configuration")
|
|
1616
|
+
}, {
|
|
1617
|
+
default: b(() => [
|
|
1618
|
+
u(d(Ke), { class: "size-5" })
|
|
1619
|
+
]),
|
|
1620
|
+
_: 1
|
|
1621
|
+
}, 8, ["aria-label", "title"])
|
|
1622
|
+
]),
|
|
1623
|
+
_: 1
|
|
1624
|
+
}, 8, ["options"]));
|
|
1625
|
+
}
|
|
1626
|
+
}), ws = /* @__PURE__ */ B({
|
|
1627
|
+
__name: "Account",
|
|
1628
|
+
setup(o) {
|
|
1629
|
+
return (s, e) => s.$solid.hasLoggedIn() ? (h(), R(is, { key: 0 })) : (h(), R(rs, { key: 1 }));
|
|
1630
|
+
}
|
|
1631
|
+
}), as = { $cloud: A };
|
|
1632
|
+
function Ms() {
|
|
1633
|
+
return {
|
|
1634
|
+
name: "@aerogel/local-first",
|
|
1635
|
+
async install(o) {
|
|
1636
|
+
wn.forEach((s) => se.addSetting(s)), await lt(o, {
|
|
1637
|
+
...as,
|
|
1638
|
+
$_documentsCache: P
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
export {
|
|
1644
|
+
ws as Account,
|
|
1645
|
+
is as AccountLoggedIn,
|
|
1646
|
+
rs as AccountLoggedOut,
|
|
1647
|
+
He as AccountLoginModal,
|
|
1648
|
+
es as AccountModal,
|
|
1649
|
+
A as Cloud,
|
|
1650
|
+
dn as CloudService,
|
|
1651
|
+
Ms as default
|
|
1652
|
+
};
|
|
1653
|
+
//# sourceMappingURL=aerogel-plugin-local-first.js.map
|