@aerogel/plugin-local-first 0.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.
Files changed (38) hide show
  1. package/dist/InruptAuthenticator.lazy-BvpQLGoj-BvpQLGoj.js +9 -0
  2. package/dist/InruptAuthenticator.lazy-BvpQLGoj-BvpQLGoj.js.map +1 -0
  3. package/dist/LegacyAuthenticator.lazy-ChFFqP14-ChFFqP14.js +5 -0
  4. package/dist/LegacyAuthenticator.lazy-ChFFqP14-ChFFqP14.js.map +1 -0
  5. package/dist/aerogel-plugin-local-first.d.ts +269 -0
  6. package/dist/aerogel-plugin-local-first.js +1686 -0
  7. package/dist/aerogel-plugin-local-first.js.map +1 -0
  8. package/package.json +50 -0
  9. package/src/components/AGCloudStatus.vue +31 -0
  10. package/src/components/index.ts +3 -0
  11. package/src/index.ts +29 -0
  12. package/src/jobs/Backup.ts +98 -0
  13. package/src/jobs/Migrate.test.ts +217 -0
  14. package/src/jobs/Migrate.ts +179 -0
  15. package/src/jobs/Sync.test.ts +982 -0
  16. package/src/jobs/Sync.ts +590 -0
  17. package/src/jobs/mixins/LoadsChildren.ts +210 -0
  18. package/src/jobs/mixins/LoadsTypeIndex.ts +23 -0
  19. package/src/jobs/mixins/TracksLocalModels.ts +32 -0
  20. package/src/lib/SyncQueue.ts +94 -0
  21. package/src/lib/inference.ts +124 -0
  22. package/src/lib/mirroring.ts +327 -0
  23. package/src/lib/utils.ts +21 -0
  24. package/src/services/Cloud.state.ts +111 -0
  25. package/src/services/Cloud.ts +450 -0
  26. package/src/services/DocumentsCache.ts +35 -0
  27. package/src/testing/cloud.ts +193 -0
  28. package/src/testing/mocks/Solid.mock.ts +34 -0
  29. package/src/testing/setup.ts +32 -0
  30. package/src/testing/stubs/LegacyTask.schema.ts +15 -0
  31. package/src/testing/stubs/Movie.schema.ts +15 -0
  32. package/src/testing/stubs/Movie.ts +3 -0
  33. package/src/testing/stubs/MoviesContainer.ts +20 -0
  34. package/src/testing/stubs/Task.schema.ts +12 -0
  35. package/src/testing/stubs/Task.ts +3 -0
  36. package/src/testing/stubs/TasksList.ts +20 -0
  37. package/src/testing/stubs/Workspace.ts +15 -0
  38. package/src/types/shims.d.ts +7 -0
@@ -0,0 +1,1686 @@
1
+ var ct = Object.defineProperty;
2
+ var dt = (n, t, e) => t in n ? ct(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
+ var g = (n, t, e) => dt(n, typeof t != "symbol" ? t + "" : t, e);
4
+ import { defineServiceState as je, requiredStringProp as ut, computedAsync as ht, Cache as ae, useForm as ft, requiredStringInput as gt, App as S, AGMarkdown as q, AGButton as O, AGForm as mt, AGInput as pt, AGLink as yt, persistent as wt, Events as d, UI as le, translateWithDefault as m, Colors as St, Storage as bt, Errors as X, Job as Ue, Service as vt, replaceExisting as ke, dispatch as ce, bootServices as Mt } from "@aerogel/core";
5
+ import { facade as ne, after as T, required as w, Storage as de, fail as N, tap as K, arrayUnique as Te, objectWithout as ye, asyncMemo as qe, hasLocationQueryParameter as j, getLocationQueryParameter as Q, arrayFilter as Ke, setAsyncMemo as Oe, urlRoot as Ct, requireUrlParse as It, objectWithoutEmpty as Rt, parseBoolean as we, arrayWithout as Ut, arr as Lt, PromisedValue as Pt, JSError as Le, map as v, isInstanceOf as A, arrayRemove as Dt, toString as At, urlRoute as xt, urlResolveDirectory as Et, requireUrlParentDirectory as Z, IndexedDBMap as $t, arrayFrom as kt, arrayChunk as Tt, mixed as Be, objectMap as qt, round as Ot, Semaphore as Ft, isArray as _t } from "@noeldemartin/utils";
6
+ import { SolidTypeIndex as J, SolidContainer as k, SolidACLAuthorization as Ge, SolidDocument as He, SolidEngine as Wt, SolidModel as F, SolidContainsRelation as Ve, isContainerClass as _, Metadata as Nt, Operation as Jt, isContainer as P, Tombstone as W, PropertyOperation as ee } from "soukai-solid";
7
+ import { fetchLoginUserProfile as zt, MalformedSolidDocumentError as Ye } from "@noeldemartin/solid-utils";
8
+ import { setEngine as jt, bootModels as Kt, requireEngine as Bt, DocumentNotFound as Gt } from "soukai";
9
+ import { defineComponent as Pe, createElementBlock as te, openBlock as D, unref as f, computed as Qe, renderSlot as V, createCommentVNode as ue, createVNode as R, createElementVNode as Fe, withCtx as L, createTextVNode as E, toDisplayString as $, createBlock as B, watchEffect as Xe, shallowRef as Ht, triggerRef as he, toRaw as fe } from "vue";
10
+ var Vt = Object.defineProperty, Yt = (n, t, e) => t in n ? Vt(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e, C = (n, t, e) => Yt(n, typeof t != "symbol" ? t + "" : t, e);
11
+ class Qt extends Le {
12
+ }
13
+ function Xt(n, t) {
14
+ return n;
15
+ }
16
+ class Se extends Le {
17
+ constructor(t, e, i) {
18
+ super(Xt(t), i), C(this, "description"), this.description = e;
19
+ }
20
+ }
21
+ class Zt extends Le {
22
+ constructor(t, e) {
23
+ super(`Container at ${t.url} is already in use`, e);
24
+ }
25
+ }
26
+ const Y = {};
27
+ class Ze {
28
+ constructor() {
29
+ C(this, "name"), C(this, "authenticatedFetch"), C(this, "booted"), C(this, "listeners", Lt([])), C(this, "_engine");
30
+ }
31
+ get engine() {
32
+ return this._engine = this._engine ?? new Wt(this.requireAuthenticatedFetch()), this._engine;
33
+ }
34
+ getAuthenticatedFetch() {
35
+ return this.authenticatedFetch ?? null;
36
+ }
37
+ requireAuthenticatedFetch() {
38
+ return this.authenticatedFetch ?? N("Authenticated fetch is not ready");
39
+ }
40
+ addListener(t) {
41
+ return this.listeners.includes(t) || this.listeners.push(t), () => {
42
+ this.removeListener(t);
43
+ };
44
+ }
45
+ removeListener(t) {
46
+ this.listeners.includes(t) && this.listeners.remove(t);
47
+ }
48
+ async boot() {
49
+ if (this.booted)
50
+ return this.booted;
51
+ this.booted = new Pt(), await this.restoreSession(), this.booted.resolve();
52
+ }
53
+ async initAuthenticatedFetch(t) {
54
+ this.authenticatedFetch = t, await this.notifyListeners("onAuthenticatedFetchReady", t);
55
+ }
56
+ async startSession(t) {
57
+ const e = {
58
+ authenticator: this,
59
+ ...t
60
+ };
61
+ return await this.notifyListeners("onSessionStarted", e), e;
62
+ }
63
+ async failSession(t, e) {
64
+ await this.notifyListeners("onSessionFailed", t, e);
65
+ }
66
+ async endSession() {
67
+ await this.notifyListeners("onSessionEnded");
68
+ }
69
+ async notifyListeners(t, ...e) {
70
+ await Promise.all(
71
+ this.listeners.toArray().map(async (i) => {
72
+ const s = i[t];
73
+ await (s == null ? void 0 : s(...e));
74
+ })
75
+ );
76
+ }
77
+ }
78
+ const ge = "inrupt-authenticator";
79
+ class ei extends Ze {
80
+ constructor() {
81
+ super(...arguments), C(this, "_events"), C(this, "_fetch"), C(this, "_login"), C(this, "_logout"), C(this, "_handleIncomingRedirect");
82
+ }
83
+ async login(t) {
84
+ de.set(ge, t);
85
+ const e = {
86
+ oidcIssuer: t
87
+ };
88
+ return Y.clientID && (e.clientId = Y.clientID.client_id, e.clientName = Y.clientID.client_name, e.redirectUrl = Y.clientID.redirect_uris[0]), await this._login(e), await T({ seconds: 60 }), N("Browser should have redirected, but it didn't");
89
+ }
90
+ async logout() {
91
+ await this._logout(), await this.endSession();
92
+ }
93
+ async restoreSession() {
94
+ const { events: t, fetch: e, handleIncomingRedirect: i, login: s, logout: o } = await import("./InruptAuthenticator.lazy-BvpQLGoj-BvpQLGoj.js");
95
+ this._fetch = e, this._login = s, this._logout = o, this._events = t, this._handleIncomingRedirect = i, await this.loginFromRedirect();
96
+ }
97
+ async loginFromRedirect() {
98
+ const t = de.get(ge);
99
+ if (!t)
100
+ return;
101
+ this._events().on("error", (i, s) => {
102
+ i ?? (i = "Error using Inrupt Authenticator method"), typeof s == "object" ? this.failSession(t, new Se(i, null, { cause: s })) : this.failSession(t, new Se(i, s));
103
+ });
104
+ const e = await this._handleIncomingRedirect(globalThis.location.href);
105
+ de.remove(ge), e != null && e.isLoggedIn && e.webId && await this.initSession(e.webId);
106
+ }
107
+ async initSession(t) {
108
+ await this.initAuthenticatedFetch(this._fetch);
109
+ try {
110
+ const e = await y.requireUserProfile(t);
111
+ await this.startSession({ user: e, loginUrl: t });
112
+ } catch (e) {
113
+ await this.failSession(t, e);
114
+ }
115
+ }
116
+ }
117
+ class ti extends Ze {
118
+ constructor() {
119
+ super(), C(this, "store"), this.store = wt("legacy-authenticator", {});
120
+ }
121
+ async login(t, e) {
122
+ const { SolidAuthClient: i } = await import("./LegacyAuthenticator.lazy-ChFFqP14-ChFFqP14.js");
123
+ throw this.store.webId = e == null ? void 0 : e.webId, this.store.loginUrl = (e == null ? void 0 : e.oidcIssuerUrl) ?? t, await i.login(this.store.loginUrl) === null ? (delete this.store.webId, delete this.store.loginUrl, new Se("Could not log in with Solid using the legacy authenticator")) : (await T({ seconds: 60 }), new Error("Browser should have redirected, but it didn't"));
124
+ }
125
+ async logout() {
126
+ const { SolidAuthClient: t } = await import("./LegacyAuthenticator.lazy-ChFFqP14-ChFFqP14.js");
127
+ delete this.store.webId, delete this.store.loginUrl, await t.logout(), await this.endSession();
128
+ }
129
+ async restoreSession() {
130
+ if (!this.store.loginUrl)
131
+ return;
132
+ const { SolidAuthClient: t } = await import("./LegacyAuthenticator.lazy-ChFFqP14-ChFFqP14.js"), e = await t.currentSession(), i = w(this.store.loginUrl);
133
+ await this.initAuthenticatedFetch((s, o) => t.fetch(s, o));
134
+ try {
135
+ const s = await y.requireUserProfile(w((e == null ? void 0 : e.webId) ?? this.store.webId));
136
+ await this.startSession({ user: s, loginUrl: i });
137
+ } catch (s) {
138
+ await this.failSession(i, s);
139
+ }
140
+ }
141
+ }
142
+ const ii = {};
143
+ new ei(), new ti();
144
+ function si(n) {
145
+ return ii[n];
146
+ }
147
+ const et = { autoReconnect: !0 }, ni = je({
148
+ name: "solid",
149
+ persist: ["autoReconnect", "dismissed", "previousSession", "profiles", "staleProfiles"],
150
+ initialState: {
151
+ autoReconnect: et.autoReconnect,
152
+ dismissed: !1,
153
+ ignorePreviousSessionError: !1,
154
+ loginStartupError: null,
155
+ loginOngoing: !1,
156
+ preferredAuthenticator: null,
157
+ previousSession: null,
158
+ profiles: {},
159
+ session: null,
160
+ loginStale: !1,
161
+ staleProfiles: []
162
+ },
163
+ serialize(n) {
164
+ var t;
165
+ return ((t = n.previousSession) == null ? void 0 : t.error) instanceof Error && (n.previousSession.error = n.previousSession.error.message), n;
166
+ },
167
+ computed: {
168
+ user: (n) => {
169
+ var t, e;
170
+ return ((t = n.session) == null ? void 0 : t.user) ?? ((e = n.previousSession) == null ? void 0 : e.profile) ?? null;
171
+ },
172
+ authenticator: (n) => {
173
+ var t;
174
+ return ((t = n.session) == null ? void 0 : t.authenticator) ?? null;
175
+ },
176
+ fetch() {
177
+ var n;
178
+ return ((n = this.authenticator) == null ? void 0 : n.getAuthenticatedFetch()) ?? globalThis.fetch.bind(globalThis);
179
+ },
180
+ error(n) {
181
+ var t;
182
+ return n.loginStartupError ? n.loginStartupError ?? null : n.ignorePreviousSessionError ? null : ((t = n.previousSession) == null ? void 0 : t.error) ?? null;
183
+ }
184
+ }
185
+ });
186
+ class oi extends ni {
187
+ isLoggedIn() {
188
+ return !!this.session;
189
+ }
190
+ wasLoggedIn() {
191
+ return !!this.previousSession;
192
+ }
193
+ hasLoggedIn() {
194
+ return !!(this.session || this.previousSession);
195
+ }
196
+ requireAuthenticator() {
197
+ return this.authenticator ?? N("Could not get authenticator");
198
+ }
199
+ requireUser() {
200
+ return this.user ?? N("Could not get user profile (are you logged in?)");
201
+ }
202
+ requireUserProfile(t) {
203
+ return this.getUserProfile(t, { required: !0 });
204
+ }
205
+ /* eslint-enable max-len */
206
+ async getUserProfile(t, e = {}) {
207
+ var i;
208
+ let s = null;
209
+ const o = e.markStale ?? !((i = this.authenticator) != null && i.getAuthenticatedFetch()), r = this.profiles[t] ?? await K(
210
+ await zt(t, {
211
+ fetch: this.fetch,
212
+ required: e.required ?? !1,
213
+ onLoaded(a) {
214
+ s = a;
215
+ }
216
+ }),
217
+ async (a) => {
218
+ a && (s && await d.emit("solid:user-profile-loaded", [a, s]), this.rememberProfile(a));
219
+ }
220
+ );
221
+ return r && o && this.setState({ staleProfiles: Te(this.staleProfiles.concat([r.webId])) }), r;
222
+ }
223
+ async refreshUserProfile() {
224
+ if (!this.isLoggedIn())
225
+ return;
226
+ this.setState({ profiles: ye(this.profiles, [this.user.webId]) });
227
+ const t = await this.requireUserProfile(this.user.webId);
228
+ this.setState({
229
+ session: {
230
+ ...this.session,
231
+ user: t
232
+ }
233
+ });
234
+ }
235
+ async login(t, e = {}) {
236
+ if (S.development && t === "dev" && (t = "http://localhost:3000"), /^https?:\/\//.test(t) || (e.fallbackUrl ?? (e.fallbackUrl = `http://${t}`), t = `https://${t}`), this.isLoggedIn())
237
+ return !0;
238
+ if (this.loginOngoing)
239
+ throw new Error("Authentication already in progress");
240
+ return e.loading ? le.loading(m("solid.loggingIn", "Logging in..."), () => this.attemptLogin(t, e)) : this.attemptLogin(t, e);
241
+ }
242
+ async reconnect(t = {}) {
243
+ const { force: e, ...i } = t;
244
+ this.isLoggedIn() || !this.previousSession || this.previousSession.error !== null && !e || await this.login(this.previousSession.loginUrl, {
245
+ authenticator: this.previousSession.authenticator,
246
+ ...i,
247
+ loading: i.loading ?? !1
248
+ });
249
+ }
250
+ async logout(t = !1) {
251
+ var e, i;
252
+ const s = !S.plugin("@aerogel/local-first") || !!((e = S.service("$cloud")) != null && e.ready), o = !S.plugin("@aerogel/local-first") || !!((i = S.service("$cloud")) != null && i.dirty), [r, a] = t ? [!0, { wipeLocalData: s }] : await le.confirm(
253
+ s ? m("solid.logoutConfirmTitle", "Log out from this device?") : m("solid.disconnectConfirmTitle", "Disconnect account?"),
254
+ s ? o ? m(
255
+ "solid.logoutConfirmMessageWithLocalChanges",
256
+ "There are some changes that haven't been synchronized and will be lost, but the rest of the data will remain in your Solid POD."
257
+ ) : m(
258
+ "solid.logoutConfirmMessage",
259
+ "Logging out will remove all the data from this device, but you'll still have it in your Solid POD."
260
+ ) : m(
261
+ "solid.disconnectConfirmMessage",
262
+ "You'll need to introduce your credentials again to connect to your Solid POD."
263
+ ),
264
+ {
265
+ acceptText: m("solid.logoutConfirmAccept", "Log out"),
266
+ acceptColor: St.Danger,
267
+ cancelText: m(
268
+ "solid.logoutConfirmCancel",
269
+ m("ui.cancel", "Cancel")
270
+ ),
271
+ checkboxes: s ? o ? {
272
+ wipeLocalData: {
273
+ label: m(
274
+ "solid.logoutConfirmWipeNotice",
275
+ "I understand that changes that haven't been synchronized will be lost."
276
+ ),
277
+ default: !1,
278
+ required: !0
279
+ }
280
+ } : void 0 : {
281
+ wipeLocalData: {
282
+ label: m(
283
+ "solid.logoutConfirmWipe",
284
+ "Also remove all existing data (tasks, lists, etc.)"
285
+ ),
286
+ default: !1
287
+ }
288
+ }
289
+ }
290
+ );
291
+ r && this.previousSession && await le.loading(m("solid.logoutOngoing", "Logging out..."), async () => {
292
+ this.setState({
293
+ dismissed: !1,
294
+ ignorePreviousSessionError: !1,
295
+ loginStartupError: null,
296
+ previousSession: null,
297
+ ...et
298
+ }), this.isLoggedIn() && await this.authenticator.logout(), (a.wipeLocalData ?? !0) && await bt.purge(), await d.emit("auth:logout"), await d.emit("auth:after-logout");
299
+ });
300
+ }
301
+ async whenLoggedIn(t) {
302
+ return this.isLoggedIn() ? t(this.session) : new Promise((e) => {
303
+ const i = (s) => e(t(s));
304
+ d.once("auth:login", i);
305
+ });
306
+ }
307
+ dismiss() {
308
+ this.setState({ dismissed: !0 });
309
+ }
310
+ async findOrCreatePrivateTypeIndex() {
311
+ return await this.findPrivateTypeIndex() ?? await this.createPrivateTypeIndex();
312
+ }
313
+ async findPrivateTypeIndex() {
314
+ const { webId: t, privateTypeIndexUrl: e } = this.requireUser(), i = this.requireAuthenticator().engine;
315
+ return e ? qe(`${t}-privateTypeIndex`, () => J.withEngine(i).find(e)) : null;
316
+ }
317
+ async findOrCreatePublicTypeIndex() {
318
+ return await this.findPublicTypeIndex() ?? await this.createPublicTypeIndex();
319
+ }
320
+ async findPublicTypeIndex() {
321
+ const { webId: t, publicTypeIndexUrl: e } = this.requireUser(), i = this.requireAuthenticator().engine;
322
+ return e ? qe(`${t}-publicTypeIndex`, () => J.withEngine(i).find(e)) : null;
323
+ }
324
+ async createPrivateContainer(t) {
325
+ const e = this.requireAuthenticator().engine;
326
+ return k.withEngine(e, async () => {
327
+ const i = await k.find(t.url);
328
+ if (i && !t.reuseExisting)
329
+ throw new Zt(i);
330
+ const s = i ?? new k({ url: t.url, name: t.name });
331
+ if (await s.save(), t.registerFor) {
332
+ const o = await this.findOrCreatePrivateTypeIndex();
333
+ await s.register(o, t.registerFor);
334
+ }
335
+ return s;
336
+ });
337
+ }
338
+ async boot() {
339
+ var t, e;
340
+ await X.booted, j("authenticator") && this.setState({
341
+ preferredAuthenticator: Q("authenticator")
342
+ }), j("refreshProfile") && this.setState({
343
+ staleProfiles: Te(
344
+ this.staleProfiles.concat(Ke([(t = this.session) == null ? void 0 : t.user.webId, (e = this.previousSession) == null ? void 0 : e.loginUrl]))
345
+ )
346
+ }), await this.restorePreviousSession(), await this.startupReconnect();
347
+ }
348
+ async createPrivateTypeIndex() {
349
+ const t = this.requireUser(), e = this.requireAuthenticator(), i = await J.withEngine(e.engine).createPrivate(t);
350
+ return K(i, () => {
351
+ t.privateTypeIndexUrl = i.url, Oe(`${t.webId}-privateTypeIndex`, i), this.rememberProfile(t);
352
+ });
353
+ }
354
+ async createPublicTypeIndex() {
355
+ const t = this.requireUser(), e = this.requireAuthenticator(), i = await J.withEngine(e.engine).createPublic(t);
356
+ return K(i, () => {
357
+ t.privateTypeIndexUrl = i.url, Oe(`${t.webId}-publicTypeIndex`, i), this.rememberProfile(t);
358
+ });
359
+ }
360
+ async attemptLogin(t, e) {
361
+ const i = e.authenticator ?? this.preferredAuthenticator ?? "default", s = e.onError ?? ((a) => S.isMounted() ? X.report(a) : this.setState({ loginStartupError: a })), o = setTimeout(() => this.loginStale = !0, 1e4), r = {
362
+ dismissed: this.dismissed,
363
+ ignorePreviousSessionError: this.ignorePreviousSessionError,
364
+ previousSession: this.previousSession
365
+ };
366
+ this.loginOngoing = !0;
367
+ try {
368
+ const a = await this.getUserProfile(t, { markStale: !0 }), l = (a == null ? void 0 : a.oidcIssuerUrl) ?? Ct((a == null ? void 0 : a.webId) ?? t), c = await this.bootAuthenticator(i), { domain: u } = It(t);
369
+ return this.setState({
370
+ dismissed: !1,
371
+ ignorePreviousSessionError: !0,
372
+ previousSession: Rt({
373
+ profile: a,
374
+ loginUrl: t,
375
+ authenticator: i,
376
+ error: m(
377
+ "auth.stuckConnecting",
378
+ `We didn't hear back from the identity provider at \`${u}\`, maybe try reconnecting?`
379
+ )
380
+ })
381
+ }), await d.emit("auth:before-login"), await c.login(l, a), !0;
382
+ } catch (a) {
383
+ return this.setState(r), a instanceof Qt ? !1 : e.fallbackUrl ? T().then(() => this.login(e.fallbackUrl ?? "", ye(e, "fallbackUrl"))) : (s(a), !1);
384
+ } finally {
385
+ clearTimeout(o), this.setState({
386
+ loginOngoing: !1,
387
+ loginStale: !1
388
+ });
389
+ }
390
+ }
391
+ async restorePreviousSession() {
392
+ this.previousSession && await this.bootAuthenticator(this.previousSession.authenticator);
393
+ }
394
+ async startupReconnect() {
395
+ this.reconnectOnStartup() && await this.reconnect({ force: this.forcingReconnect() });
396
+ }
397
+ reconnectOnStartup() {
398
+ return j("autoReconnect") ? we(Q("autoReconnect")) : this.autoReconnect;
399
+ }
400
+ forcingReconnect() {
401
+ return j("autoReconnect") && we(Q("autoReconnect"));
402
+ }
403
+ async bootAuthenticator(t) {
404
+ const e = si(t);
405
+ return e.addListener({
406
+ onSessionStarted: async (i) => {
407
+ this.setState({
408
+ session: i,
409
+ previousSession: {
410
+ authenticator: e.name,
411
+ loginUrl: i.loginUrl,
412
+ profile: i.user,
413
+ error: null
414
+ }
415
+ }), this.staleProfiles.includes(i.user.webId) && await this.refreshUserProfile(), S.plugin("@aerogel/local-first") || jt(i.authenticator.engine), Ge.setEngine(i.authenticator.engine), J.setEngine(i.authenticator.engine), He.setEngine(i.authenticator.engine), await d.emit("auth:login", i);
416
+ },
417
+ onSessionFailed: async (i, s) => {
418
+ var o;
419
+ this.setState({
420
+ session: null,
421
+ previousSession: {
422
+ profile: (o = this.previousSession) == null ? void 0 : o.profile,
423
+ authenticator: e.name,
424
+ loginUrl: i,
425
+ error: s
426
+ }
427
+ });
428
+ },
429
+ onSessionEnded: () => this.setState({ session: null }),
430
+ onAuthenticatedFetchReady: (i) => d.emit("auth:fetch-ready", i)
431
+ }), await e.boot(), e;
432
+ }
433
+ rememberProfile(t) {
434
+ this.setState({
435
+ profiles: {
436
+ ...this.profiles,
437
+ [t.webId]: t
438
+ },
439
+ staleProfiles: Ut(this.staleProfiles, t.webId)
440
+ });
441
+ }
442
+ }
443
+ const y = ne(oi), ri = ["src"];
444
+ ut();
445
+ const ai = { class: "flex flex-col gap-3" }, li = { class: "flex flex-col" }, ci = {
446
+ key: 1,
447
+ class: "mt-1 self-center text-sm text-red-800"
448
+ }, di = /* @__PURE__ */ Pe({
449
+ __name: "AGSolidStatus",
450
+ setup(n) {
451
+ const t = ft({ url: gt() }), e = Qe(
452
+ () => S.development && (!t.url || t.url === "dev" || t.url.trim().length === 0)
453
+ );
454
+ return (i, s) => (D(), te("div", null, [
455
+ i.$solid.loginStale ? V(i.$slots, "login-stale", { key: 0 }, () => [
456
+ R(f(q), {
457
+ text: i.$td("solid.loginStale", "This is taking too long...")
458
+ }, null, 8, ["text"])
459
+ ]) : ue("", !0),
460
+ i.$solid.loginOngoing ? V(i.$slots, "login-ongoing", { key: 1 }, () => [
461
+ R(f(q), {
462
+ text: i.$td("ui.loading", "Loading...")
463
+ }, null, 8, ["text"])
464
+ ]) : i.$solid.isLoggedIn() ? V(i.$slots, "logged-in", {
465
+ key: 2,
466
+ session: i.$solid.session
467
+ }, () => [
468
+ Fe("div", ai, [
469
+ R(f(q), {
470
+ text: i.$td("solid.loggedIn", "You are logged in as [{userName}]({userWebId})", {
471
+ userName: i.$solid.user.name ?? i.$solid.user.webId,
472
+ userWebId: i.$solid.user.webId
473
+ })
474
+ }, null, 8, ["text"]),
475
+ R(f(O), {
476
+ onClick: s[0] || (s[0] = (o) => i.$solid.logout())
477
+ }, {
478
+ default: L(() => [
479
+ E($(i.$td("solid.logout", "Logout")), 1)
480
+ ]),
481
+ _: 1
482
+ })
483
+ ])
484
+ ]) : V(i.$slots, "logged-out", { key: 3 }, () => {
485
+ var o;
486
+ return [
487
+ Fe("div", li, [
488
+ R(f(mt), {
489
+ form: f(t),
490
+ class: "flex",
491
+ onSubmit: s[2] || (s[2] = (r) => i.$solid.login(f(t).url))
492
+ }, {
493
+ default: L(() => [
494
+ R(f(pt), {
495
+ name: "url",
496
+ "aria-label": i.$td("solid.url", "Login url"),
497
+ placeholder: i.$td("solid.placeholder", "https://...")
498
+ }, null, 8, ["aria-label", "placeholder"]),
499
+ e.value ? (D(), B(f(O), {
500
+ key: 0,
501
+ submit: "",
502
+ onClick: s[1] || (s[1] = (r) => f(t).url = "dev")
503
+ }, {
504
+ default: L(() => [
505
+ E($(i.$td("solid.devLogin", "Dev login")), 1)
506
+ ]),
507
+ _: 1
508
+ })) : (D(), B(f(O), {
509
+ key: 1,
510
+ submit: ""
511
+ }, {
512
+ default: L(() => [
513
+ E($(i.$td("solid.login", "Login")), 1)
514
+ ]),
515
+ _: 1
516
+ }))
517
+ ]),
518
+ _: 1
519
+ }, 8, ["form"]),
520
+ i.$solid.wasLoggedIn() ? (D(), B(f(O), {
521
+ key: 0,
522
+ class: "mt-3",
523
+ onClick: s[3] || (s[3] = (r) => i.$solid.reconnect({ force: !0 }))
524
+ }, {
525
+ default: L(() => [
526
+ E($(i.$td("solid.reconnect", "Reconnect")), 1)
527
+ ]),
528
+ _: 1
529
+ })) : ue("", !0),
530
+ (o = i.$solid.previousSession) != null && o.error || i.$solid.loginStartupError ? (D(), te("p", ci, [
531
+ R(f(q), {
532
+ text: i.$td("solid.previousLoginError", "Previous login attempt failed"),
533
+ inline: ""
534
+ }, null, 8, ["text"]),
535
+ R(f(yt), {
536
+ onClick: s[4] || (s[4] = (r) => {
537
+ var a;
538
+ return i.$errors.inspect(((a = i.$solid.previousSession) == null ? void 0 : a.error) || i.$solid.loginStartupError);
539
+ })
540
+ }, {
541
+ default: L(() => [
542
+ E(" (" + $(i.$td("errors.viewDetails", "View details")) + ") ", 1)
543
+ ]),
544
+ _: 1
545
+ })
546
+ ])) : ue("", !0)
547
+ ])
548
+ ];
549
+ })
550
+ ]));
551
+ }
552
+ });
553
+ let De = /* @__PURE__ */ new WeakMap();
554
+ function ui(n) {
555
+ const t = Ht(v([], "id")), e = Qe(() => t.value.getItems()), i = /* @__PURE__ */ new Set([n.collection]), s = {
556
+ modelsMap: t,
557
+ modelsArray: e,
558
+ collectionsSet: i,
559
+ async refresh() {
560
+ const o = v([], "id");
561
+ for (const r of i)
562
+ (await n.withCollection(r, () => n.all())).forEach((a) => o.add(a));
563
+ t.value = o;
564
+ }
565
+ };
566
+ return De.set(n, s), n.on("created", (o) => (t.value.add(fe(o)), he(t))), n.on("deleted", (o) => (t.value.delete(fe(o)), he(t))), n.on("updated", (o) => (t.value.add(fe(o)), he(t))), d.on("purge-storage", () => t.value = v([], "id")), d.on("cloud:migration-completed", () => s.refresh()), d.on("cloud:migration-cancelled", () => s.refresh()), d.on("cloud:backup-completed", () => s.refresh()), s;
567
+ }
568
+ function Ae() {
569
+ return De;
570
+ }
571
+ function hi(n) {
572
+ return De.get(n) ?? ui(n);
573
+ }
574
+ function xe(n) {
575
+ var t;
576
+ return ((t = Ae().get(n)) == null ? void 0 : t.modelsArray.value) ?? [];
577
+ }
578
+ function fi(n, t) {
579
+ w(
580
+ Ae().get(n),
581
+ "Failed ignoring models collection, please track the model first using trackModels()"
582
+ ).collectionsSet.delete(t);
583
+ }
584
+ async function ie(n, t, e = {}) {
585
+ const i = e.refresh ?? !0, s = w(
586
+ Ae().get(n),
587
+ "Failed tracking models collection, please track the model first using trackModels()"
588
+ );
589
+ if (!s.collectionsSet.has(t) && (s.collectionsSet.add(t), i)) {
590
+ const o = s.modelsArray.value;
591
+ (await n.withCollection(t, () => n.all())).forEach((r) => o.push(r)), s.modelsMap.value = v(o, "id");
592
+ }
593
+ }
594
+ async function gi(n, t) {
595
+ const { service: e, property: i, transform: s, ...o } = t ?? {}, r = s ?? ((l) => l), a = hi(n);
596
+ for (const [l, c] of Object.entries(o))
597
+ n.on(l, c);
598
+ e && i && Xe(() => e.setState(i, r(a.modelsArray.value))), await a.refresh();
599
+ }
600
+ const me = /* @__PURE__ */ new WeakMap();
601
+ function be(n) {
602
+ return Ke(
603
+ M(n).map((t) => {
604
+ const e = n.instance().requireRelation(t).relatedClass;
605
+ return _(e) ? !1 : e;
606
+ })
607
+ );
608
+ }
609
+ function M(n) {
610
+ return me.has(n) || me.set(
611
+ n,
612
+ n.relations.filter((t) => F.reservedRelations.includes(t) ? !1 : n.instance().requireRelation(t) instanceof Ve)
613
+ ), me.get(n) ?? [];
614
+ }
615
+ function tt(n) {
616
+ return M(n.static()).reduce(
617
+ (e, i) => e.concat(n.getRelationModels(i) ?? []),
618
+ []
619
+ );
620
+ }
621
+ function _e(n) {
622
+ const t = /* @__PURE__ */ new Set(), e = n.instance();
623
+ t.add(n);
624
+ for (const i of n.relations)
625
+ n.reservedRelations.includes(i) || t.add(e.requireRelation(i).relatedClass);
626
+ return [...t.values()];
627
+ }
628
+ function ve(n) {
629
+ return n.getRelatedModels().filter(
630
+ (t) => !A(t, Ge) && !A(t, He) && !A(t, Nt) && !A(t, Jt) && t.static() !== k
631
+ );
632
+ }
633
+ function it(n) {
634
+ if (n.isDirty())
635
+ return !0;
636
+ if (!(n instanceof k))
637
+ return !1;
638
+ const t = (e) => {
639
+ var i;
640
+ return (i = n.getRelationModels(e)) == null ? void 0 : i.some((s) => it(s));
641
+ };
642
+ return M(n.static()).some(t);
643
+ }
644
+ const mi = w(() => S.service("$cloud"));
645
+ class pi {
646
+ constructor() {
647
+ g(this, "models", /* @__PURE__ */ new Set());
648
+ g(this, "promises", []);
649
+ }
650
+ push(t) {
651
+ this.models.add(t), this.syncAfter(T({ seconds: 1 }));
652
+ }
653
+ clear(t) {
654
+ if (!t) {
655
+ this.models = /* @__PURE__ */ new Set();
656
+ return;
657
+ }
658
+ for (const e of t)
659
+ this.models.delete(e);
660
+ }
661
+ async syncAfter(t) {
662
+ const e = typeof t == "function" ? t() : t;
663
+ return this.promises.push(e), e.then(() => Dt(this.promises, e)), this.promises.length === 1 && this.schedule(), e;
664
+ }
665
+ schedule() {
666
+ Promise.all(this.promises).then(() => T()).then(() => {
667
+ if (this.promises.length !== 0) {
668
+ this.schedule();
669
+ return;
670
+ }
671
+ const t = this.consume();
672
+ t.length !== 0 && mi.syncIfOnline(t);
673
+ });
674
+ }
675
+ consume() {
676
+ const t = [], e = /* @__PURE__ */ new Set();
677
+ for (const i of this.models)
678
+ P(i) && (this.models.delete(i), tt(i).forEach((s) => e.add(s)), t.push(i));
679
+ for (const i of this.models)
680
+ this.models.delete(i), !e.has(i) && t.push(i);
681
+ return t;
682
+ }
683
+ }
684
+ const se = ne(pi), h = w(() => S.service("$cloud")), st = /* @__PURE__ */ new WeakMap(), Ee = /* @__PURE__ */ new WeakMap();
685
+ function yi(n) {
686
+ const t = n.getRelatedModels().concat([n]);
687
+ for (const e of t)
688
+ e.cleanDirty(!0);
689
+ }
690
+ function wi(n) {
691
+ const t = ve(n).concat([n]);
692
+ for (const e of t) {
693
+ if (!e.operations || e.operations.length === 0)
694
+ continue;
695
+ const i = (e.operations ?? []).filter((s) => !(s instanceof ee) || !e.ignoreRdfPropertyHistory(s.property, !0));
696
+ if (!i.some((s) => !s.isInception(e))) {
697
+ e.setRelationModels("operations", []);
698
+ continue;
699
+ }
700
+ e.setRelationModels("operations", i);
701
+ }
702
+ }
703
+ async function We(n) {
704
+ h.setState({
705
+ localModelUpdates: {
706
+ ...h.localModelUpdates,
707
+ [n.url]: 1
708
+ }
709
+ }), Ui(n.static()) && await Me(n.static(), Z(n.url)), h.autoPush && h.ready && !h.syncing && se.push(n);
710
+ }
711
+ async function Me(n, t) {
712
+ var e;
713
+ (e = h.modelCollections[n.modelName]) != null && e.includes(t) || (h.setState("modelCollections", {
714
+ ...h.modelCollections,
715
+ [n.modelName]: (h.modelCollections[n.modelName] ?? []).concat(t)
716
+ }), await ie(n, t));
717
+ }
718
+ async function Ne(n) {
719
+ if (Si(n))
720
+ return;
721
+ const t = h.localModelUpdates[n.url] ?? 0;
722
+ h.setState({
723
+ localModelUpdates: n.isSoftDeleted() ? ye(h.localModelUpdates, n.url) : {
724
+ ...h.localModelUpdates,
725
+ [n.url]: t + 1
726
+ }
727
+ }), h.autoPush && h.ready && !h.syncing && se.push(n);
728
+ }
729
+ function Ce(n, t) {
730
+ const e = n == null ? void 0 : n.map((s) => At(s.getDeletedPrimaryKey() ?? s.getPrimaryKey())), i = {};
731
+ for (const [s, o] of Object.entries(h.localModelUpdates)) {
732
+ const r = xt(s);
733
+ (!e || e.some(
734
+ (l) => s === l || l.endsWith("/") && s.startsWith(l)
735
+ )) && !(t != null && t.has(r)) || (i[s] = o);
736
+ }
737
+ h.setState({ localModelUpdates: i });
738
+ }
739
+ function $e(n, t = {}) {
740
+ const e = /* @__PURE__ */ new Set();
741
+ if (e.add(n.static()), n instanceof k)
742
+ for (const s of M(n.static()))
743
+ e.add(n.requireRelation(s).relatedClass);
744
+ const i = [...e.values()].map(
745
+ (s) => [s, x(s)]
746
+ );
747
+ return K(n.clone({ constructors: i }), (s) => {
748
+ wi(s), t.clean && yi(s);
749
+ });
750
+ }
751
+ function nt(n) {
752
+ const t = /* @__PURE__ */ new Set();
753
+ if (t.add(n.static()), n instanceof k)
754
+ for (const i of M(n.static()))
755
+ t.add(n.requireRelation(i).relatedClass);
756
+ const e = [...t.values()].map(
757
+ (i) => [i, Pi(i)]
758
+ );
759
+ return n.clone({ constructors: e });
760
+ }
761
+ async function Je(n, t, e) {
762
+ const i = x(W), s = t.map((a) => a.url), o = n.filter((a) => !s.includes(a.url)).map((a) => a.requireDocumentUrl()).filter((a) => !e.has(a)), r = await i.all({ $in: o });
763
+ return t.concat(r);
764
+ }
765
+ function Si(n) {
766
+ var e;
767
+ const t = (e = n.metadata.updatedAt) == null ? void 0 : e.getTime();
768
+ return !n.operations.some((i) => i.date.getTime() !== t ? !1 : i instanceof ee ? !n.ignoreRdfPropertyHistory(i.property, !0) : !0);
769
+ }
770
+ function bi(n, t) {
771
+ return t.get(n.url) ?? nt(n);
772
+ }
773
+ function Ie() {
774
+ return [...h.registeredModels].map(({ modelClass: n }) => xe(n)).flat();
775
+ }
776
+ function vi() {
777
+ return h.schemaMigrations;
778
+ }
779
+ function Mi() {
780
+ h.schemaMigrations.clear();
781
+ }
782
+ function ze(n) {
783
+ return h.schemaMigrations.get(n);
784
+ }
785
+ function x(n) {
786
+ return st.get(n) ?? Li(n);
787
+ }
788
+ function pe(n) {
789
+ const t = y.requireUser().storageUrls[0];
790
+ return n ? Et((n.startsWith("/") ? t.slice(0, -1) : t) + n) : t;
791
+ }
792
+ function Ci(n, t) {
793
+ return t.get(n.url) ?? $e(n);
794
+ }
795
+ function Ii(n) {
796
+ for (const { modelClass: t } of h.registeredModels)
797
+ if (xe(t).some((i) => i.url === n.url))
798
+ return !0;
799
+ return !1;
800
+ }
801
+ function Re(n) {
802
+ return Ee.has(n.static());
803
+ }
804
+ function Ri(n) {
805
+ return !Re(n);
806
+ }
807
+ function Ui(n) {
808
+ return h.registeredModels.some(({ modelClass: t }) => t === n);
809
+ }
810
+ function Li(n) {
811
+ var s;
812
+ const t = n, e = (o, r) => {
813
+ o.timestamps = t.timestamps, o.history = t.history, r(), o.timestamps = [], o.history = !1;
814
+ }, i = (s = class extends t {
815
+ initialize(o, r) {
816
+ e(this._proxy.static(), () => super.initialize(o, r));
817
+ }
818
+ initializeRelations() {
819
+ super.initializeRelations();
820
+ for (const o of Object.values(this._relations))
821
+ o instanceof Ve && (o.relatedClass = x(o.relatedClass));
822
+ }
823
+ fixMalformedAttributes() {
824
+ e(this.static(), () => super.fixMalformedAttributes());
825
+ }
826
+ }, g(s, "timestamps", !1), g(s, "history", !1), s);
827
+ return st.set(t, i), Ee.set(i, t), t.on("schema-updated", async (o) => {
828
+ await i.updateSchema({
829
+ ...o,
830
+ timestamps: !1,
831
+ history: !1
832
+ });
833
+ }), Kt({ [`Remote${n.modelName}`]: i }), i;
834
+ }
835
+ function Pi(n) {
836
+ return Ee.get(n) ?? N(`Couldn't find local class for ${n.modelName}`);
837
+ }
838
+ class Di extends Ue {
839
+ constructor() {
840
+ super(...arguments);
841
+ g(this, "urlMigrations", []);
842
+ g(this, "collectionMigrations", []);
843
+ }
844
+ migrateUrl(e, i, s) {
845
+ this.urlMigrations.push({
846
+ modelClass: e,
847
+ local: i,
848
+ remote: s
849
+ });
850
+ }
851
+ migrateCollection(e, i, s) {
852
+ this.collectionMigrations.push({
853
+ modelClass: e,
854
+ local: i,
855
+ remote: s
856
+ });
857
+ }
858
+ async run() {
859
+ const e = Bt(), i = await e.getCollections();
860
+ for (const s of i) {
861
+ const o = await e.readMany(s);
862
+ for (const [r, a] of Object.entries(o)) {
863
+ const l = this.replaceUrl(r);
864
+ await e.create(Z(l), this.replaceDocumentUrls(a), l), await e.delete(s, r);
865
+ }
866
+ }
867
+ for (const { modelClass: s, remote: o } of this.urlMigrations)
868
+ ie(s, Z(o), { refresh: !1 });
869
+ for (const { modelClass: s, local: o, remote: r } of this.collectionMigrations)
870
+ fi(s, o), ie(s, r, { refresh: !1 });
871
+ }
872
+ replaceDocumentUrls(e) {
873
+ for (const [i, s] of Object.entries(e)) {
874
+ if (i === "@id" && typeof s == "string") {
875
+ e[i] = this.replaceUrl(s);
876
+ continue;
877
+ }
878
+ typeof s != "object" || s === null || (e[i] = this.replaceDocumentUrls(s));
879
+ }
880
+ return e;
881
+ }
882
+ replaceUrl(e) {
883
+ for (const { local: i, remote: s } of this.urlMigrations)
884
+ if (e.startsWith(i))
885
+ return e.replace(i, s);
886
+ for (const { local: i, remote: s } of this.collectionMigrations)
887
+ if (e.startsWith(i))
888
+ return e.replace(i, s);
889
+ return e;
890
+ }
891
+ }
892
+ class Ai extends vt {
893
+ constructor() {
894
+ super(...arguments);
895
+ g(this, "cache", new $t("documents-cache"));
896
+ }
897
+ async isFresh(e, i) {
898
+ const s = await this.cache.get(e), o = typeof i != "number" ? i.getTime() : i;
899
+ return !!(s != null && s.modifiedAt) && s.modifiedAt >= o;
900
+ }
901
+ async remember(e, i) {
902
+ await this.cache.set(e, {
903
+ modifiedAt: typeof i != "number" ? i.getTime() : i
904
+ });
905
+ }
906
+ async forget(e) {
907
+ await this.cache.delete(e);
908
+ }
909
+ async boot() {
910
+ d.on("auth:logout", async () => {
911
+ await this.cache.clear(), this.cache.close();
912
+ });
913
+ }
914
+ }
915
+ const G = ne(Ai);
916
+ function xi(n) {
917
+ const t = {};
918
+ return async () => ("value" in t || (t.value = await n()), t.value);
919
+ }
920
+ class ot {
921
+ async loadContainedModels(t, e = {}) {
922
+ var u;
923
+ if (Ri(t)) {
924
+ const p = [];
925
+ for (const I of M(t.static())) {
926
+ const U = await t.loadRelationIfUnloaded(I) ?? [];
927
+ p.push(...kt(U));
928
+ }
929
+ return p;
930
+ }
931
+ const i = {}, s = [], o = v(t.documents, "url"), r = Tt(t.resourceUrls, 10), a = r.flat().map((p) => ({
932
+ documentUrl: p,
933
+ completed: !1
934
+ })), l = v(a, "documentUrl");
935
+ e.status && (e.status.children = a);
936
+ for (const p of r) {
937
+ await Promise.all(
938
+ p.map(async (I) => {
939
+ const { children: U, tombstones: H } = await this.loadDocumentChildren(t, I, o, e.onMalformedDocument);
940
+ s.push(...H);
941
+ for (const [re, lt] of Object.entries(U))
942
+ (i[re] ?? (i[re] = [])).push(...lt);
943
+ })
944
+ );
945
+ for (const I of p)
946
+ I.endsWith("/") || (w(l.get(I)).completed = !0);
947
+ await ((u = e.onLoaded) == null ? void 0 : u.call(e, p));
948
+ }
949
+ for (const [p, I] of Object.entries(i))
950
+ t.setRelationModels(p, I);
951
+ const c = e.ignoreTombstones ? Object.values(i).flat() : Object.values(i).flat().concat(s);
952
+ return e.status && (e.status.children = c.map((p) => w(l.get(p.requireDocumentUrl())))), c;
953
+ }
954
+ async loadDocumentChildren(t, e, i, s) {
955
+ var r;
956
+ const o = i.get(e);
957
+ return o && await G.isFresh(o.url, o.updatedAt ?? /* @__PURE__ */ new Date()) && ((r = this.localModels) != null && r.hasKey(t.url)) ? {
958
+ children: await this.loadDocumentChildrenFromLocal(t, o),
959
+ tombstones: []
960
+ } : this.loadDocumentChildrenFromRemote(t, e, s);
961
+ }
962
+ async loadDocumentChildrenFromLocal(t, e) {
963
+ var s, o;
964
+ const i = {};
965
+ for (const r of M(t.static())) {
966
+ const a = t.requireRelation(r);
967
+ if (a.loaded) {
968
+ i[r] = a.getLoadedModels();
969
+ continue;
970
+ }
971
+ const l = ((o = (s = this.localModels) == null ? void 0 : s.get(t.url)) == null ? void 0 : o.getRelationModels(r)) ?? [];
972
+ i[r] = l.filter((c) => c.getDocumentUrl() === e.url).map((c) => $e(c, { clean: !0 }));
973
+ }
974
+ return i;
975
+ }
976
+ async loadDocumentChildrenFromRemote(t, e, i) {
977
+ const s = {}, o = [], r = xi(async () => {
978
+ try {
979
+ const a = await t.requireEngine().readOne(t.static("collection"), e), l = await W.createManyFromEngineDocuments({
980
+ [e]: a
981
+ });
982
+ return o.push(...l), a;
983
+ } catch (a) {
984
+ if (A(a, Gt))
985
+ return null;
986
+ if (A(a, Ye))
987
+ return console.warn(a.message), await (i == null ? void 0 : i(e)), null;
988
+ throw a;
989
+ }
990
+ });
991
+ for (const a of M(t.static())) {
992
+ const l = t.requireRelation(a);
993
+ if (l.loaded) {
994
+ s[a] = l.getLoadedModels();
995
+ continue;
996
+ }
997
+ const c = await r();
998
+ if (!c)
999
+ continue;
1000
+ const u = await l.relatedClass.createManyFromEngineDocuments({
1001
+ [e]: c
1002
+ });
1003
+ s[a] = u;
1004
+ }
1005
+ return { children: s, tombstones: o };
1006
+ }
1007
+ }
1008
+ const z = /* @__PURE__ */ new WeakMap();
1009
+ class rt {
1010
+ async loadTypeIndex(t = {}) {
1011
+ const e = y.requireUser();
1012
+ return t.create && !z.get(e) ? z.set(e, await y.findOrCreatePrivateTypeIndex()) : z.has(e) || z.set(e, await y.findPrivateTypeIndex()), z.get(e) ?? null;
1013
+ }
1014
+ }
1015
+ class at {
1016
+ async indexLocalModels(t) {
1017
+ for (const e of t)
1018
+ await this.addLocalModel(e);
1019
+ }
1020
+ async addLocalModel(t) {
1021
+ if (!(!this.localModels || this.localModels.hasKey(t.url))) {
1022
+ this.localModels.add(t);
1023
+ for (const e of M(t.static()))
1024
+ await t.loadRelationIfUnloaded(e);
1025
+ for (const e of t.getRelatedModels())
1026
+ await this.addLocalModel(e);
1027
+ }
1028
+ }
1029
+ }
1030
+ const Ei = Ue;
1031
+ class oe extends Be(Ei, [ot, rt, at]) {
1032
+ constructor() {
1033
+ super(...arguments);
1034
+ g(this, "_models");
1035
+ }
1036
+ static restore(e) {
1037
+ return K(new oe(), (i) => {
1038
+ i.status = e;
1039
+ });
1040
+ }
1041
+ get models() {
1042
+ return this._models;
1043
+ }
1044
+ set models(e) {
1045
+ if (!e) {
1046
+ delete this._models, delete this.localModels;
1047
+ return;
1048
+ }
1049
+ const i = qt(this.status.children ?? [], "modelUrl");
1050
+ this._models = e, this.localModels = v([], "url"), this.status.children = e.map(
1051
+ (s) => i[s.url] ?? {
1052
+ modelUrl: s.url,
1053
+ completed: !1
1054
+ }
1055
+ );
1056
+ }
1057
+ async run() {
1058
+ if (!this.models)
1059
+ throw new Error("Cant start migration without models");
1060
+ await this.indexLocalModels(this.models);
1061
+ const e = this.status.children ?? [], i = await this.loadTypeIndex();
1062
+ for (const s of e) {
1063
+ const o = this.models.find(({ url: r }) => s.modelUrl === r);
1064
+ !o || s.completed || (await this.migrateRegisteredModel(o, s, i), await this.updateProgress(() => s.completed = !0));
1065
+ }
1066
+ for (const [s, o] of vi())
1067
+ await s.updateSchema(o);
1068
+ Mi();
1069
+ }
1070
+ async migrateRegisteredModel(e, i, s) {
1071
+ if (await this.migrate(e, i), !P(e))
1072
+ return;
1073
+ const o = be(e.static()), r = s == null ? void 0 : s.registrations.find(({ instanceContainer: a }) => a === e.url);
1074
+ !s || !r || o.length === 0 || (r.setAttribute(
1075
+ "forClass",
1076
+ o.map((a) => {
1077
+ var l;
1078
+ return ((l = ze(a)) == null ? void 0 : l.rdfsClasses) ?? a.rdfsClass;
1079
+ }).flat()
1080
+ ), await s.save());
1081
+ }
1082
+ async migrate(e, i) {
1083
+ this.assertNotCancelled(), await this.migrateChildren(e, i);
1084
+ const s = ze(e.static());
1085
+ if (!s)
1086
+ return;
1087
+ const o = await x(e.static()).find(e.url), r = await (o == null ? void 0 : o.migrateSchema(s));
1088
+ await e.migrateSchema(s, {
1089
+ mintOperationUrl: (a) => {
1090
+ var l, c;
1091
+ return (c = (l = r == null ? void 0 : r.operations) == null ? void 0 : l.find((u) => !A(a, ee) || !A(u, ee) ? !1 : a.property === u.property && a.date.getTime() === u.date.getTime())) == null ? void 0 : c.url;
1092
+ }
1093
+ });
1094
+ }
1095
+ async migrateChildren(e, i) {
1096
+ if (!P(e))
1097
+ return;
1098
+ const s = await this.loadContainedModels(e, { ignoreTombstones: !0 });
1099
+ i.children ?? (i.children = s.map((o) => ({
1100
+ modelUrl: o.url,
1101
+ completed: !1
1102
+ })));
1103
+ for (const o of i.children) {
1104
+ const r = s.find(({ url: a }) => o.modelUrl === a);
1105
+ !r || o.completed || (await this.migrate(r, o), await this.updateProgress(() => o.completed = !0));
1106
+ }
1107
+ }
1108
+ }
1109
+ const $i = w(() => S.service("$cloud")), ki = Ue;
1110
+ function Ti(n) {
1111
+ return !!n && "root" in n;
1112
+ }
1113
+ class qi extends Be(ki, [ot, rt, at]) {
1114
+ constructor(e) {
1115
+ super();
1116
+ g(this, "models");
1117
+ g(this, "dirtyRemoteModels");
1118
+ g(this, "rootLocalModels");
1119
+ g(this, "tombstones");
1120
+ g(this, "malformedDocuments");
1121
+ g(this, "documentsModifiedAt");
1122
+ g(this, "localModels");
1123
+ this.models = e, this.rootLocalModels = [], this.localModels = v([], "url"), this.tombstones = v([], "resourceUrl"), this.malformedDocuments = /* @__PURE__ */ new Set(), this.documentsModifiedAt = {};
1124
+ }
1125
+ async run() {
1126
+ const e = y.requireAuthenticator().engine, i = (o, { headers: r }) => {
1127
+ const a = r == null ? void 0 : r.get("last-modified");
1128
+ !a || o.endsWith("/") || (this.documentsModifiedAt[o] = new Date(a));
1129
+ }, s = e.listeners.add({
1130
+ onDocumentRead: i,
1131
+ onDocumentUpdated: i
1132
+ });
1133
+ try {
1134
+ this.rootLocalModels = this.models ?? Ie(), await this.indexLocalModels(this.rootLocalModels), await this.pullChanges(), await this.pushChanges();
1135
+ } finally {
1136
+ s();
1137
+ }
1138
+ }
1139
+ getInitialStatus() {
1140
+ return {
1141
+ root: !0,
1142
+ completed: !1,
1143
+ children: [{ completed: !1 }, { completed: !1 }]
1144
+ };
1145
+ }
1146
+ calculateCurrentProgress(e) {
1147
+ return e ?? (e = this.status), Ti(e) ? Ot(
1148
+ this.calculateCurrentProgress(e.children[0]) * 0.9 + this.calculateCurrentProgress(e.children[1]) * 0.1,
1149
+ 2
1150
+ ) : super.calculateCurrentProgress(e);
1151
+ }
1152
+ async pullChanges() {
1153
+ const e = this.models ? await this.fetchRemoteModelsForLocal(this.models) : await this.fetchRemoteModels(), i = v(e, (s) => s instanceof W ? s.resourceUrl : s.url);
1154
+ this.dirtyRemoteModels = await this.synchronizeModels(i), await this.updateProgress((s) => s.children[0].completed = !0);
1155
+ }
1156
+ async pushChanges() {
1157
+ const e = this.dirtyRemoteModels ?? [], i = this.status.children[1].children = e.map(() => ({ completed: !1 }));
1158
+ for (let s = 0; s < e.length; s++) {
1159
+ const o = e[s], r = i[s];
1160
+ if (o.isSoftDeleted()) {
1161
+ o.enableHistory(), o.enableTombstone(), await o.delete(), await this.updateProgress(() => r.completed = !0);
1162
+ return;
1163
+ }
1164
+ await this.saveModelAndChildren(o, r), await this.updateTypeRegistrations(o), await this.updateProgress(() => r.completed = !0);
1165
+ }
1166
+ for (const [s, o] of Object.entries(this.documentsModifiedAt))
1167
+ await G.remember(s, o);
1168
+ Ce(this.models, this.malformedDocuments), await this.updateProgress((s) => s.children[1].completed = !0);
1169
+ }
1170
+ async fetchRemoteModels() {
1171
+ const e = this.status.children[0], i = await this.loadTypeIndex();
1172
+ if (!i)
1173
+ return [];
1174
+ const s = [], o = /* @__PURE__ */ new Set(), r = [...$i.registeredModels].map(({ modelClass: l }) => {
1175
+ const c = _(l) ? be(l) : [];
1176
+ return {
1177
+ modelClass: l,
1178
+ rdfsClasses: c.length > 0 ? c.map((u) => u.rdfsClasses).flat() : l.rdfsClasses
1179
+ };
1180
+ }), a = i.registrations.map((l) => {
1181
+ const c = r.find(
1182
+ ({ rdfsClasses: u }) => !!l.instanceContainer && u.some((p) => l.forClass.includes(p))
1183
+ );
1184
+ return !c || !l.instanceContainer || o.has(l.instanceContainer) ? null : (o.add(l.instanceContainer), [l, c]);
1185
+ }).filter((l) => !!l);
1186
+ e.children = a.map(() => ({ completed: !1 }));
1187
+ for (let l = 0; l < a.length; l++)
1188
+ await this.ignoringMalformedDocumentErrors(async () => {
1189
+ var I;
1190
+ const c = w(a[l])[0], u = w(a[l])[1], p = x(u.modelClass);
1191
+ if (c.instanceContainer) {
1192
+ if (_(p)) {
1193
+ await Me(
1194
+ u.modelClass,
1195
+ Z(c.instanceContainer)
1196
+ );
1197
+ const U = await p.find(c.instanceContainer);
1198
+ U && (await this.loadChildren(U, w((I = e.children) == null ? void 0 : I[l])), s.push(U)), await this.updateProgress(() => {
1199
+ var H;
1200
+ return w((H = e.children) == null ? void 0 : H[l]).completed = !0;
1201
+ });
1202
+ return;
1203
+ }
1204
+ await Me(u.modelClass, c.instanceContainer), s.push(...await p.from(c.instanceContainer).all()), await this.updateProgress(() => {
1205
+ var U;
1206
+ return w((U = e.children) == null ? void 0 : U[l]).completed = !0;
1207
+ });
1208
+ }
1209
+ });
1210
+ return Je(this.rootLocalModels, s, this.malformedDocuments);
1211
+ }
1212
+ async fetchRemoteModelsForLocal(e) {
1213
+ const i = [], s = this.status.children[0].children = e.map(() => ({ completed: !1 }));
1214
+ for (let o = 0; o < e.length; o++)
1215
+ await this.ignoringMalformedDocumentErrors(async () => {
1216
+ const r = e[o], a = s[o], l = await x(r.static()).find(r.url);
1217
+ if (!l) {
1218
+ await this.updateProgress(() => a.completed = !0);
1219
+ return;
1220
+ }
1221
+ P(l) && await this.loadChildren(l, a), i.push(l), await this.updateProgress(() => a.completed = !0);
1222
+ });
1223
+ return Je(e, i, this.malformedDocuments);
1224
+ }
1225
+ async updateTypeRegistrations(e) {
1226
+ if (!P(e) || !Ii(e))
1227
+ return;
1228
+ const i = be(e.static());
1229
+ if (i.length === 0)
1230
+ return;
1231
+ const s = await this.loadTypeIndex({ create: !0 });
1232
+ s.registrations.some((o) => o.instanceContainer === e.url) || await e.register(s, i);
1233
+ }
1234
+ async loadChildren(e, i) {
1235
+ var o, r;
1236
+ if (this.assertNotCancelled(), !P(e))
1237
+ return;
1238
+ const s = await this.loadContainedModels(e, {
1239
+ status: i,
1240
+ onLoaded: async () => {
1241
+ this.assertNotCancelled(), await this.updateProgress();
1242
+ },
1243
+ onMalformedDocument: (a) => this.malformedDocuments.add(a)
1244
+ });
1245
+ for (let a = 0; a < s.length; a++) {
1246
+ const l = s[a];
1247
+ if (l instanceof W) {
1248
+ this.tombstones.add(l);
1249
+ continue;
1250
+ }
1251
+ if (this.tombstones.hasKey(l.url)) {
1252
+ await this.deleteChild(e, l);
1253
+ continue;
1254
+ }
1255
+ await this.loadChildren(l, (o = i == null ? void 0 : i.children) == null ? void 0 : o[a]), (r = i == null ? void 0 : i.children) != null && r[a] && await this.updateProgress(() => {
1256
+ var c;
1257
+ return w((c = i.children) == null ? void 0 : c[a]).completed = !0;
1258
+ });
1259
+ }
1260
+ }
1261
+ async deleteChild(e, i) {
1262
+ for (const s of e.static("relations")) {
1263
+ const o = e.requireRelation(s);
1264
+ if (o.related) {
1265
+ if (Array.isArray(o.related)) {
1266
+ o.related = o.related.filter((r) => r !== i);
1267
+ continue;
1268
+ }
1269
+ if (o.related === i) {
1270
+ o.related = null;
1271
+ continue;
1272
+ }
1273
+ }
1274
+ }
1275
+ await i.delete();
1276
+ }
1277
+ async saveModelAndChildren(e, i) {
1278
+ if (this.assertNotCancelled(), Re(e) && e.isSoftDeleted()) {
1279
+ e.enableHistory(), e.enableTombstone(), await e.delete();
1280
+ return;
1281
+ }
1282
+ if (this.malformedDocuments.has(e.requireDocumentUrl()))
1283
+ return;
1284
+ if (await e.save(), !P(e)) {
1285
+ if (Re(e)) {
1286
+ const r = e.requireDocumentUrl(), a = this.documentsModifiedAt[r] ?? /* @__PURE__ */ new Date();
1287
+ await G.remember(r, a), delete this.documentsModifiedAt[r];
1288
+ }
1289
+ return;
1290
+ }
1291
+ const s = M(e.static()).map((r) => e.getRelationModels(r) ?? []).flat(), o = i ? s.map(() => ({ completed: !1 })) : [];
1292
+ i && (i.children = o);
1293
+ for (let r = 0; r < s.length; r++) {
1294
+ const a = s[r], l = o[r];
1295
+ await this.saveModelAndChildren(a, l), l && await this.updateProgress(() => l.completed = !0);
1296
+ }
1297
+ }
1298
+ async synchronizeModels(e) {
1299
+ const i = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set();
1300
+ for (const r of e.items()) {
1301
+ if (r instanceof W) {
1302
+ const l = this.localModels.get(r.resourceUrl);
1303
+ l && (await l.delete(), s.add(l));
1304
+ continue;
1305
+ }
1306
+ const a = bi(r, this.localModels);
1307
+ await this.loadChildren(a), await F.synchronize(a, r), await this.reconcileInconsistencies(a, r), await this.saveModelAndChildren(a), await this.addLocalModel(a), this.rootLocalModels.push(a), i.add(a.url);
1308
+ }
1309
+ for (const r of this.rootLocalModels) {
1310
+ if (s.has(r) || i.has(r.url))
1311
+ continue;
1312
+ await this.loadChildren(r);
1313
+ const a = Ci(r, e);
1314
+ await F.synchronize(r, a), e.add(a);
1315
+ }
1316
+ const o = [];
1317
+ for (const r of e.getItems()) {
1318
+ if (it(r)) {
1319
+ o.push(r);
1320
+ continue;
1321
+ }
1322
+ await this.rememberModelDocuments(r);
1323
+ }
1324
+ return o;
1325
+ }
1326
+ async reconcileInconsistencies(e, i, s) {
1327
+ e.rebuildAttributesFromHistory(), e.setAttributes(i.getAttributes(!0)), s ?? (s = /* @__PURE__ */ new Set()), s.add(e);
1328
+ for (const r of M(e.static()))
1329
+ await this.synchronizeContainerDocuments(
1330
+ e.requireRelation(r),
1331
+ i.requireRelation(r)
1332
+ );
1333
+ const o = v(ve(i), "url");
1334
+ for (const r of ve(e))
1335
+ s.has(r) || !r.isRelationLoaded("operations") || !o.hasKey(r.url) || await this.reconcileInconsistencies(r, o.require(r.url));
1336
+ e.isDirty() && (await e.save(), await F.synchronize(e, i));
1337
+ }
1338
+ async synchronizeContainerDocuments(e, i) {
1339
+ const s = v(e.related ?? [], "url"), o = v(i.related ?? [], "url"), r = s.getKeys().filter((l) => !o.hasKey(l) && !o.hasKey(encodeURI(l))), a = o.getKeys().filter((l) => !s.hasKey(l) && !s.hasKey(encodeURI(l)));
1340
+ for (const l of r) {
1341
+ const c = s.require(l), u = $e(c);
1342
+ i.addRelated(u), o.add(u);
1343
+ }
1344
+ for (const l of a) {
1345
+ const c = o.require(l), u = nt(c);
1346
+ e.addRelated(u), s.add(u);
1347
+ }
1348
+ for (const l of s.items()) {
1349
+ const c = o.require(l.url);
1350
+ await F.synchronize(l, c), await this.saveModelAndChildren(l);
1351
+ }
1352
+ }
1353
+ async rememberModelDocuments(e) {
1354
+ if (!P(e)) {
1355
+ const s = e.requireDocumentUrl(), o = this.documentsModifiedAt[s] ?? /* @__PURE__ */ new Date();
1356
+ await G.remember(s, o), delete this.documentsModifiedAt[s];
1357
+ return;
1358
+ }
1359
+ const i = M(e.static()).map((s) => e.getRelationModels(s) ?? []).flat();
1360
+ for (const s of i)
1361
+ await this.rememberModelDocuments(s);
1362
+ }
1363
+ async ignoringMalformedDocumentErrors(e) {
1364
+ try {
1365
+ await e();
1366
+ } catch (i) {
1367
+ if (A(i, Ye)) {
1368
+ console.warn(i.message), i.documentUrl && this.malformedDocuments.add(i.documentUrl);
1369
+ return;
1370
+ }
1371
+ throw i;
1372
+ }
1373
+ }
1374
+ }
1375
+ const b = {
1376
+ Disconnected: "disconnected",
1377
+ Online: "online",
1378
+ Syncing: "syncing",
1379
+ Migrating: "migrating"
1380
+ }, Oi = je({
1381
+ name: "cloud",
1382
+ persist: [
1383
+ "localModelUpdates",
1384
+ "migrationDismissed",
1385
+ "migrationJob",
1386
+ "modelCollections",
1387
+ "pollingEnabled",
1388
+ "pollingMinutes",
1389
+ "ready",
1390
+ "startupSync"
1391
+ ],
1392
+ initialState: () => ({
1393
+ autoPush: !0,
1394
+ localModelUpdates: {},
1395
+ migrationDismissed: !1,
1396
+ migrationJob: null,
1397
+ migrationPostponed: !1,
1398
+ modelCollections: {},
1399
+ pollingEnabled: !0,
1400
+ pollingMinutes: 10,
1401
+ ready: !1,
1402
+ registeredModels: [],
1403
+ schemaMigrations: /* @__PURE__ */ new Map(),
1404
+ setupDismissed: !1,
1405
+ setupOngoing: !1,
1406
+ startupSync: !0,
1407
+ status: b.Disconnected,
1408
+ syncError: null,
1409
+ syncJob: null
1410
+ }),
1411
+ serialize: (n) => {
1412
+ var t;
1413
+ return ke(n, { migrationJob: (t = n.migrationJob) == null ? void 0 : t.serialize() });
1414
+ },
1415
+ restore: (n) => ke(n, {
1416
+ migrationJob: n.migrationJob && oe.restore(n.migrationJob)
1417
+ }),
1418
+ watch: {
1419
+ migrationJob(n) {
1420
+ n == null || n.listeners.add({ onUpdated: () => this.updatePersistedState("migrationJob") });
1421
+ }
1422
+ },
1423
+ computed: {
1424
+ disconnected: ({ status: n }) => n === b.Disconnected,
1425
+ online: ({ status: n }) => n === b.Online,
1426
+ syncing: ({ status: n }) => n === b.Syncing,
1427
+ migrating: ({ status: n }) => n === b.Migrating,
1428
+ localChanges({ localModelUpdates: n }) {
1429
+ return Object.values(n).reduce((t, e) => t + e, 0);
1430
+ },
1431
+ dirty() {
1432
+ return this.localChanges > 0;
1433
+ },
1434
+ migrationStarted({ migrationJob: n }) {
1435
+ return !!n;
1436
+ },
1437
+ migrationDisabledReason({ status: n, ready: t }) {
1438
+ return y.isLoggedIn() ? t ? n === b.Syncing || n === b.Migrating ? m(
1439
+ "cloud.migrationNotSyncing",
1440
+ "Wait for syncing to finish before starting the migration"
1441
+ ) : this.online ? null : m(
1442
+ "cloud.migrationNotOnline",
1443
+ "You need to be online in order to start the migration"
1444
+ ) : m(
1445
+ "cloud.migrationNotReady",
1446
+ "You need to backup your data before starting the migration"
1447
+ ) : m(
1448
+ "cloud.migrationNotLoggedIn",
1449
+ "You need to reconnect before starting the migration"
1450
+ );
1451
+ }
1452
+ }
1453
+ });
1454
+ class Fi extends Oi {
1455
+ constructor() {
1456
+ super(...arguments);
1457
+ g(this, "asyncLock", new Ft());
1458
+ g(this, "engine", null);
1459
+ g(this, "pollingInterval", null);
1460
+ }
1461
+ async whenReady(e) {
1462
+ return this.ready ? e() : new Promise((i) => {
1463
+ const s = () => i(e());
1464
+ d.once("cloud:ready", s);
1465
+ });
1466
+ }
1467
+ async setup(e) {
1468
+ this.setupOngoing = !0;
1469
+ try {
1470
+ await this.backup(e), await this.setReady(!0), await this.sync();
1471
+ } finally {
1472
+ this.setupOngoing = !1;
1473
+ }
1474
+ }
1475
+ dismissSetup() {
1476
+ this.setupDismissed = !0;
1477
+ }
1478
+ dismissMigration() {
1479
+ this.migrationDismissed = !0;
1480
+ }
1481
+ postponeMigration() {
1482
+ this.migrationPostponed = !0;
1483
+ }
1484
+ async syncIfOnline(e = {}) {
1485
+ this.online && await this.sync(e);
1486
+ }
1487
+ async sync(e = {}) {
1488
+ const i = _t(e) ? { models: e } : e instanceof F ? { model: e } : e;
1489
+ !y.isLoggedIn() || !this.ready || !this.online || await this.asyncLock.run(async () => {
1490
+ const s = Date.now(), o = i.model ? [i.model] : i.models;
1491
+ this.syncError = null, this.status = b.Syncing, se.clear(o);
1492
+ try {
1493
+ if (await d.emit("cloud:sync-started", o), i.refreshUserProfile && await y.refreshUserProfile(), this.syncJob = new qi(o), this.syncJob.listeners.add(i), await ce(this.syncJob), this.syncJob.cancelled)
1494
+ return;
1495
+ S.testing || await T({ milliseconds: Math.max(500, 1e3 - (Date.now() - s)) }), this.syncJob = null;
1496
+ } catch (r) {
1497
+ if (S.testing)
1498
+ throw r;
1499
+ this.syncJob = null, this.syncError = r, await X.report(r, m("cloud.syncFailed", "Sync failed"));
1500
+ } finally {
1501
+ this.status = b.Online, await d.emit("cloud:sync-completed", o);
1502
+ }
1503
+ });
1504
+ }
1505
+ shouldMigrate() {
1506
+ return this.schemaMigrations.size > 0;
1507
+ }
1508
+ async migrate(e) {
1509
+ if (!this.online || !y.isLoggedIn() || !this.ready)
1510
+ throw new Error("Data cannot be migrated at the moment");
1511
+ this.shouldMigrate() && await this.asyncLock.run(async () => {
1512
+ var r;
1513
+ this.status = b.Migrating, this.migrationJob ?? (this.migrationJob = new oe());
1514
+ const i = Date.now(), s = [], o = (r = this.migrationJob).models ?? (r.models = Ie());
1515
+ se.clear(o);
1516
+ try {
1517
+ if (e && s.push(this.migrationJob.listeners.add(e)), await d.emit("cloud:migration-started", o), await ce(this.migrationJob), this.migrationJob.cancelled) {
1518
+ await d.emit("cloud:migration-cancelled", o);
1519
+ return;
1520
+ }
1521
+ this.migrationJob = null, this.migrationDismissed = !1, this.migrationPostponed = !1, await T({ milliseconds: Math.max(0, 1e3 - (Date.now() - i)) }), await d.emit("cloud:migration-completed", o);
1522
+ } catch (a) {
1523
+ await X.report(a, m("cloud.migrationFailed", "Migration failed"));
1524
+ } finally {
1525
+ this.status = b.Online, s.forEach((a) => a == null ? void 0 : a());
1526
+ }
1527
+ });
1528
+ }
1529
+ async register(e, i = {}) {
1530
+ if (this.registeredModels.find((o) => e === o.modelClass))
1531
+ return;
1532
+ const s = this.engine;
1533
+ s && _e(e).forEach((o) => x(o).setEngine(s)), this.whenReady(() => {
1534
+ _(e) && (e.collection = pe(i.path));
1535
+ }), await gi(e, {
1536
+ created: (o) => We(o),
1537
+ updated: (o) => Ne(o),
1538
+ deleted: (o) => Ce([o])
1539
+ }), _(e) && M(e).forEach((o) => {
1540
+ const r = e.instance().requireRelation(o).relatedClass;
1541
+ r.on("created", (a) => We(a)), r.on("updated", (a) => Ne(a)), r.on("deleted", (a) => Ce([a]));
1542
+ }), this.registeredModels.push({ modelClass: e, path: i.path });
1543
+ for (const o of this.modelCollections[e.modelName] ?? [])
1544
+ await ie(e, o);
1545
+ }
1546
+ registerSchemaMigration(e, i) {
1547
+ this.schemaMigrations.set(e, i);
1548
+ }
1549
+ requireRemoteCollection(e) {
1550
+ for (const i of this.registeredModels)
1551
+ if (e === i.modelClass)
1552
+ return pe(i.path);
1553
+ throw new Error(`Failed resolving remote collection for '${e.modelName}' model`);
1554
+ }
1555
+ async boot() {
1556
+ await y.booted, y.isLoggedIn() && this.login(y.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()), Xe(() => {
1557
+ if (this.pollingInterval && clearInterval(this.pollingInterval), !this.pollingEnabled || this.migrationJob) {
1558
+ this.pollingInterval = null;
1559
+ return;
1560
+ }
1561
+ this.pollingInterval = setInterval(() => this.sync(), this.pollingMinutes * 60 * 1e3);
1562
+ });
1563
+ }
1564
+ getDirtyLocalModels() {
1565
+ const e = Object.keys(this.localModelUpdates), i = [];
1566
+ for (const { modelClass: s } of this.registeredModels)
1567
+ for (const o of xe(s))
1568
+ i.push(...this.getModelsIn(e, o));
1569
+ return i;
1570
+ }
1571
+ getModelsIn(e, i) {
1572
+ const s = [];
1573
+ return e.includes(i.url) && s.push(i), P(i) && s.push(
1574
+ ...tt(i).map((o) => this.getModelsIn(e, o)).flat()
1575
+ ), s;
1576
+ }
1577
+ requireEngine() {
1578
+ return this.engine ?? N("Could not get required Engine");
1579
+ }
1580
+ async setReady(e) {
1581
+ this.ready || !e || (await d.emit("cloud:ready"), this.ready = !0);
1582
+ }
1583
+ async backup(e) {
1584
+ await d.emit("cloud:backup-started"), e ?? (e = /* @__PURE__ */ new WeakMap());
1585
+ const i = new Di();
1586
+ for (const { modelClass: s, path: o } of this.registeredModels) {
1587
+ if (!_(s))
1588
+ continue;
1589
+ for (const [l, c] of Object.entries(e.get(s) ?? {}))
1590
+ i.migrateUrl(s, l, c);
1591
+ const r = s.collection, a = pe(o);
1592
+ s.collection = a, i.migrateCollection(s, r, a);
1593
+ }
1594
+ await ce(i), await d.emit("cloud:backup-completed");
1595
+ }
1596
+ async onApplicationReady() {
1597
+ this.ready || !y.isLoggedIn() || await this.setReady(!Ie().some((e) => e.url.startsWith("solid://")));
1598
+ }
1599
+ async onApplicationMounted() {
1600
+ this.syncOnStartup() && await this.sync();
1601
+ }
1602
+ login(e) {
1603
+ const i = [...this.registeredModels].map(({ modelClass: s }) => _e(s)).flat().concat([W]);
1604
+ this.status = b.Online, this.engine = e.engine;
1605
+ for (const s of i)
1606
+ x(s).setEngine(this.engine);
1607
+ }
1608
+ logout() {
1609
+ this.setState({
1610
+ localModelUpdates: {},
1611
+ migrationDismissed: !1,
1612
+ migrationJob: null,
1613
+ migrationPostponed: !1,
1614
+ modelCollections: {},
1615
+ pollingEnabled: !0,
1616
+ pollingMinutes: 10,
1617
+ ready: !1,
1618
+ setupDismissed: !1,
1619
+ setupOngoing: !1,
1620
+ startupSync: !0,
1621
+ status: b.Disconnected
1622
+ });
1623
+ }
1624
+ syncOnStartup() {
1625
+ return j("startupSync") ? we(Q("startupSync")) : this.migrationJob ? !1 : this.startupSync;
1626
+ }
1627
+ }
1628
+ const _i = ne(Fi), Wi = {
1629
+ key: 1,
1630
+ class: "flex flex-col gap-3"
1631
+ }, Yi = /* @__PURE__ */ Pe({
1632
+ __name: "AGCloudStatus",
1633
+ emits: ["sync"],
1634
+ setup(n) {
1635
+ return (t, e) => (D(), B(f(di), null, {
1636
+ "logged-in": L(({ session: i }) => [
1637
+ t.$cloud.syncing ? (D(), B(f(q), {
1638
+ key: 0,
1639
+ text: t.$td("cloud.syncing", "Syncing...")
1640
+ }, null, 8, ["text"])) : (D(), te("div", Wi, [
1641
+ R(f(q), {
1642
+ text: t.$td("solid.loggedIn", "You are logged in as [{userName}]({userWebId})", {
1643
+ userName: i.user.name ?? i.user.webId,
1644
+ userWebId: i.user.webId
1645
+ })
1646
+ }, null, 8, ["text"]),
1647
+ R(f(O), {
1648
+ onClick: e[0] || (e[0] = (s) => (t.$cloud.sync(), t.$emit("sync")))
1649
+ }, {
1650
+ default: L(() => [
1651
+ E($(t.$td("cloud.sync", "Synchronize")), 1)
1652
+ ]),
1653
+ _: 1
1654
+ }),
1655
+ R(f(O), {
1656
+ onClick: e[1] || (e[1] = (s) => t.$solid.logout())
1657
+ }, {
1658
+ default: L(() => [
1659
+ E($(t.$td("solid.logout", "Logout")), 1)
1660
+ ]),
1661
+ _: 1
1662
+ })
1663
+ ]))
1664
+ ]),
1665
+ _: 1
1666
+ }));
1667
+ }
1668
+ }), Ni = { $cloud: _i };
1669
+ function Qi() {
1670
+ return {
1671
+ name: "@aerogel/local-first",
1672
+ async install(n) {
1673
+ await Mt(n, {
1674
+ ...Ni,
1675
+ $_documentsCache: G
1676
+ });
1677
+ }
1678
+ };
1679
+ }
1680
+ export {
1681
+ Yi as AGCloudStatus,
1682
+ _i as Cloud,
1683
+ Fi as CloudService,
1684
+ Qi as default
1685
+ };
1686
+ //# sourceMappingURL=aerogel-plugin-local-first.js.map