@carlonicora/nextjs-jsonapi 6.13.1 → 6.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BlockNoteEditor-UBVEUFNR.js → BlockNoteEditor-CUNH4LSQ.js} +25 -25
- package/dist/{BlockNoteEditor-UBVEUFNR.js.map → BlockNoteEditor-CUNH4LSQ.js.map} +1 -1
- package/dist/{BlockNoteEditor-VXMDSQAA.mjs → BlockNoteEditor-QIVV2OB4.mjs} +10 -10
- package/dist/{BlockNoteViewer-2XYASA5Y.js → BlockNoteViewer-APBOPT4B.js} +8 -8
- package/dist/{BlockNoteViewer-2XYASA5Y.js.map → BlockNoteViewer-APBOPT4B.js.map} +1 -1
- package/dist/{BlockNoteViewer-NBW2H6LC.mjs → BlockNoteViewer-HIUAJQRI.mjs} +7 -7
- package/dist/JsonApiRequest-G4J2WTSU.js +26 -0
- package/dist/{JsonApiRequest-WISJZSDE.js.map → JsonApiRequest-G4J2WTSU.js.map} +1 -1
- package/dist/{JsonApiRequest-F6TMJ42G.mjs → JsonApiRequest-IKKHWCPB.mjs} +2 -2
- package/dist/billing/index.js +497 -497
- package/dist/billing/index.mjs +9 -9
- package/dist/{chunk-7DBJTNSU.mjs → chunk-4RPGFQBA.mjs} +2 -2
- package/dist/{chunk-BZ5J2FIV.js → chunk-4XLDBOSE.js} +11 -11
- package/dist/{chunk-BZ5J2FIV.js.map → chunk-4XLDBOSE.js.map} +1 -1
- package/dist/{chunk-27LQDGNP.mjs → chunk-4ZJIUTIV.mjs} +6 -1
- package/dist/chunk-4ZJIUTIV.mjs.map +1 -0
- package/dist/{chunk-PXDUJ47N.js → chunk-6RCZ64BQ.js} +18 -18
- package/dist/{chunk-PXDUJ47N.js.map → chunk-6RCZ64BQ.js.map} +1 -1
- package/dist/{chunk-7JZHPMGW.mjs → chunk-A3RB47X4.mjs} +44 -20
- package/dist/chunk-A3RB47X4.mjs.map +1 -0
- package/dist/{chunk-DOCIFE6A.mjs → chunk-AUD6ZLBB.mjs} +3 -3
- package/dist/{chunk-GB6DBFYY.js → chunk-DGN3PR2F.js} +3 -3
- package/dist/{chunk-GB6DBFYY.js.map → chunk-DGN3PR2F.js.map} +1 -1
- package/dist/{chunk-7ZHTPFFT.js → chunk-DJXSCARG.js} +15 -15
- package/dist/{chunk-7ZHTPFFT.js.map → chunk-DJXSCARG.js.map} +1 -1
- package/dist/{chunk-QKNGZDSQ.js → chunk-GM4VZTWL.js} +2 -2
- package/dist/{chunk-QKNGZDSQ.js.map → chunk-GM4VZTWL.js.map} +1 -1
- package/dist/{chunk-PYRZCKC2.js → chunk-GSRTVIIK.js} +923 -923
- package/dist/{chunk-PYRZCKC2.js.map → chunk-GSRTVIIK.js.map} +1 -1
- package/dist/{chunk-47BBY5KA.mjs → chunk-HAW5PNJG.mjs} +4 -4
- package/dist/{chunk-YRKIFYOE.mjs → chunk-KTGKW72G.mjs} +27 -8
- package/dist/chunk-KTGKW72G.mjs.map +1 -0
- package/dist/{chunk-PV4Z5W6V.js → chunk-KV4N7DEG.js} +19 -19
- package/dist/{chunk-PV4Z5W6V.js.map → chunk-KV4N7DEG.js.map} +1 -1
- package/dist/{chunk-ZLTOUZN2.mjs → chunk-M3N7LPHX.mjs} +4 -4
- package/dist/{chunk-DGWOVYEC.mjs → chunk-MQ7TXALH.mjs} +2 -2
- package/dist/{chunk-W62MHDWM.js → chunk-N5ZE2Z6I.js} +58 -34
- package/dist/chunk-N5ZE2Z6I.js.map +1 -0
- package/dist/{chunk-2SV4SS6N.js → chunk-OQQ7CZWT.js} +12 -12
- package/dist/{chunk-2SV4SS6N.js.map → chunk-OQQ7CZWT.js.map} +1 -1
- package/dist/{chunk-JJMMT24D.mjs → chunk-OUEYZOLB.mjs} +2 -2
- package/dist/{chunk-XXP3TQHF.mjs → chunk-OY65RYD3.mjs} +2 -2
- package/dist/{chunk-MOGEGWXW.js → chunk-PMESKNKL.js} +868 -868
- package/dist/{chunk-MOGEGWXW.js.map → chunk-PMESKNKL.js.map} +1 -1
- package/dist/{chunk-B6JGKDP2.js → chunk-QGVVF77L.js} +48 -29
- package/dist/chunk-QGVVF77L.js.map +1 -0
- package/dist/{chunk-BH6JWIKI.mjs → chunk-QIEF7HIL.mjs} +2 -2
- package/dist/{chunk-P445QGOC.mjs → chunk-RFKSJIQB.mjs} +7 -7
- package/dist/{chunk-6JUCIWDC.mjs → chunk-UOTHRJD2.mjs} +2 -2
- package/dist/{chunk-KMW7UNL2.js → chunk-WCEYT3GG.js} +8 -8
- package/dist/{chunk-KMW7UNL2.js.map → chunk-WCEYT3GG.js.map} +1 -1
- package/dist/{chunk-MHB36MYE.js → chunk-WUNSG3IN.js} +7 -2
- package/dist/chunk-WUNSG3IN.js.map +1 -0
- package/dist/{chunk-N4RZZKL5.mjs → chunk-YKNULEHB.mjs} +12 -12
- package/dist/{chunk-Z4POQWFG.js → chunk-ZYSNJKOP.js} +4 -4
- package/dist/{chunk-Z4POQWFG.js.map → chunk-ZYSNJKOP.js.map} +1 -1
- package/dist/client/index.js +10 -10
- package/dist/client/index.mjs +9 -9
- package/dist/components/index.js +10 -10
- package/dist/components/index.mjs +9 -9
- package/dist/contexts/index.js +10 -10
- package/dist/contexts/index.mjs +9 -9
- package/dist/core/index.js +7 -7
- package/dist/core/index.mjs +6 -6
- package/dist/email-automations/index.js +99 -99
- package/dist/email-automations/index.mjs +9 -9
- package/dist/features/analytics/index.js +126 -126
- package/dist/features/analytics/index.mjs +9 -9
- package/dist/features/analytics/server.js +10 -10
- package/dist/features/analytics/server.mjs +8 -8
- package/dist/features/blog/index.js +156 -156
- package/dist/features/blog/index.mjs +9 -9
- package/dist/features/blog/server.js +28 -28
- package/dist/features/blog/server.mjs +7 -7
- package/dist/features/help/index.js +43 -43
- package/dist/features/help/index.mjs +9 -9
- package/dist/features/tokenusage/index.js +132 -132
- package/dist/features/tokenusage/index.mjs +9 -9
- package/dist/index.js +8 -8
- package/dist/index.mjs +7 -7
- package/dist/{lifecycle-LKGPRBS7.mjs → lifecycle-KI3PCJSE.mjs} +3 -3
- package/dist/lifecycle-TO65I7TO.js +23 -0
- package/dist/{lifecycle-4GUOTB46.js.map → lifecycle-TO65I7TO.js.map} +1 -1
- package/dist/local-transport-4YDJ6FQG.js +15 -0
- package/dist/{local-transport-7H3SPZSA.js.map → local-transport-4YDJ6FQG.js.map} +1 -1
- package/dist/local-transport-C7YTA4I7.mjs +15 -0
- package/dist/offline/index.d.mts +160 -4
- package/dist/offline/index.d.ts +160 -4
- package/dist/offline/index.js +210 -163
- package/dist/offline/index.js.map +1 -1
- package/dist/offline/index.mjs +76 -29
- package/dist/offline/index.mjs.map +1 -1
- package/dist/request-66FGJIHB.mjs +10 -0
- package/dist/request-6W6UGKJV.js +10 -0
- package/dist/{request-KTBV6HHH.js.map → request-6W6UGKJV.js.map} +1 -1
- package/dist/server/index.js +9 -9
- package/dist/server/index.mjs +8 -8
- package/dist/write-through-BAPS24GL.js +15 -0
- package/dist/{write-through-FDQ7N4YI.js.map → write-through-BAPS24GL.js.map} +1 -1
- package/dist/write-through-IWQKXYHE.mjs +15 -0
- package/package.json +1 -1
- package/src/offline/__tests__/generic-answers.spec.ts +146 -3
- package/src/offline/__tests__/local-transport.spec.ts +15 -1
- package/src/offline/__tests__/offline-fixtures.ts +29 -2
- package/src/offline/__tests__/write-through.spec.ts +27 -1
- package/src/offline/config.ts +9 -0
- package/src/offline/generic-answers.ts +44 -17
- package/src/offline/index.ts +2 -0
- package/src/offline/local-transport.ts +5 -3
- package/src/offline/sync/__tests__/runtime.spec.ts +30 -1
- package/src/offline/sync/__tests__/sync-fixtures.ts +22 -0
- package/src/offline/sync/__tests__/sync-root.spec.ts +184 -1
- package/src/offline/sync/known-roots.ts +29 -7
- package/src/offline/sync/runtime.ts +3 -2
- package/src/offline/sync/sync-root.ts +70 -19
- package/src/offline/types.ts +39 -1
- package/src/offline/write-through.ts +6 -3
- package/dist/JsonApiRequest-WISJZSDE.js +0 -26
- package/dist/chunk-27LQDGNP.mjs.map +0 -1
- package/dist/chunk-7JZHPMGW.mjs.map +0 -1
- package/dist/chunk-B6JGKDP2.js.map +0 -1
- package/dist/chunk-MHB36MYE.js.map +0 -1
- package/dist/chunk-W62MHDWM.js.map +0 -1
- package/dist/chunk-YRKIFYOE.mjs.map +0 -1
- package/dist/lifecycle-4GUOTB46.js +0 -23
- package/dist/local-transport-7H3SPZSA.js +0 -15
- package/dist/local-transport-QYFKA6AN.mjs +0 -15
- package/dist/request-KTBV6HHH.js +0 -10
- package/dist/request-SQOUNWZ4.mjs +0 -10
- package/dist/write-through-FDQ7N4YI.js +0 -15
- package/dist/write-through-R25VQMH6.mjs +0 -15
- /package/dist/{BlockNoteEditor-VXMDSQAA.mjs.map → BlockNoteEditor-QIVV2OB4.mjs.map} +0 -0
- /package/dist/{BlockNoteViewer-NBW2H6LC.mjs.map → BlockNoteViewer-HIUAJQRI.mjs.map} +0 -0
- /package/dist/{JsonApiRequest-F6TMJ42G.mjs.map → JsonApiRequest-IKKHWCPB.mjs.map} +0 -0
- /package/dist/{chunk-7DBJTNSU.mjs.map → chunk-4RPGFQBA.mjs.map} +0 -0
- /package/dist/{chunk-DOCIFE6A.mjs.map → chunk-AUD6ZLBB.mjs.map} +0 -0
- /package/dist/{chunk-47BBY5KA.mjs.map → chunk-HAW5PNJG.mjs.map} +0 -0
- /package/dist/{chunk-ZLTOUZN2.mjs.map → chunk-M3N7LPHX.mjs.map} +0 -0
- /package/dist/{chunk-DGWOVYEC.mjs.map → chunk-MQ7TXALH.mjs.map} +0 -0
- /package/dist/{chunk-JJMMT24D.mjs.map → chunk-OUEYZOLB.mjs.map} +0 -0
- /package/dist/{chunk-XXP3TQHF.mjs.map → chunk-OY65RYD3.mjs.map} +0 -0
- /package/dist/{chunk-BH6JWIKI.mjs.map → chunk-QIEF7HIL.mjs.map} +0 -0
- /package/dist/{chunk-P445QGOC.mjs.map → chunk-RFKSJIQB.mjs.map} +0 -0
- /package/dist/{chunk-6JUCIWDC.mjs.map → chunk-UOTHRJD2.mjs.map} +0 -0
- /package/dist/{chunk-N4RZZKL5.mjs.map → chunk-YKNULEHB.mjs.map} +0 -0
- /package/dist/{lifecycle-LKGPRBS7.mjs.map → lifecycle-KI3PCJSE.mjs.map} +0 -0
- /package/dist/{local-transport-QYFKA6AN.mjs.map → local-transport-C7YTA4I7.mjs.map} +0 -0
- /package/dist/{request-SQOUNWZ4.mjs.map → request-66FGJIHB.mjs.map} +0 -0
- /package/dist/{write-through-R25VQMH6.mjs.map → write-through-IWQKXYHE.mjs.map} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunk6RCZ64BQjs = require('./chunk-6RCZ64BQ.js');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -10,41 +10,59 @@ var _chunkPXDUJ47Njs = require('./chunk-PXDUJ47N.js');
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunkN5ZE2Z6Ijs = require('./chunk-N5ZE2Z6I.js');
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
var _chunkWUNSG3INjs = require('./chunk-WUNSG3IN.js');
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
var _chunk7QVYU63Ejs = require('./chunk-7QVYU63E.js');
|
|
23
24
|
|
|
24
25
|
// src/offline/sync/known-roots.ts
|
|
25
26
|
var _lastSyncRoots = [];
|
|
26
|
-
|
|
27
|
+
var _lastExtraSyncRoots = [];
|
|
28
|
+
function rememberSyncRoots(ids, extraIds = []) {
|
|
27
29
|
_lastSyncRoots = [...ids];
|
|
30
|
+
_lastExtraSyncRoots = [...extraIds];
|
|
28
31
|
}
|
|
29
32
|
_chunk7QVYU63Ejs.__name.call(void 0, rememberSyncRoots, "rememberSyncRoots");
|
|
30
33
|
async function knownRootIds(store) {
|
|
31
|
-
const config =
|
|
34
|
+
const config = _chunkWUNSG3INjs.getOfflineConfig.call(void 0, );
|
|
32
35
|
const ids = new Set(_lastSyncRoots);
|
|
33
|
-
for (const
|
|
36
|
+
for (const kind of _chunkWUNSG3INjs.rootKinds.call(void 0, config)) {
|
|
37
|
+
for (const record of await store.listRecords({ type: kind.module.name })) ids.add(record.id);
|
|
38
|
+
}
|
|
34
39
|
for (const entry of await store.queue()) ids.add(entry.rootId);
|
|
35
40
|
return [...ids].sort();
|
|
36
41
|
}
|
|
37
42
|
_chunk7QVYU63Ejs.__name.call(void 0, knownRootIds, "knownRootIds");
|
|
43
|
+
async function extraRootIds(store) {
|
|
44
|
+
const ids = new Set(_lastExtraSyncRoots);
|
|
45
|
+
for (const kind of _nullishCoalesce(_chunkWUNSG3INjs.getOfflineConfig.call(void 0, ).extraRootKinds, () => ( []))) {
|
|
46
|
+
for (const record of await store.listRecords({ type: kind.module.name })) ids.add(record.id);
|
|
47
|
+
}
|
|
48
|
+
return ids;
|
|
49
|
+
}
|
|
50
|
+
_chunk7QVYU63Ejs.__name.call(void 0, extraRootIds, "extraRootIds");
|
|
51
|
+
async function knownPrimaryRootIds(store) {
|
|
52
|
+
const extra = await extraRootIds(store);
|
|
53
|
+
return (await knownRootIds(store)).filter((id) => !extra.has(id));
|
|
54
|
+
}
|
|
55
|
+
_chunk7QVYU63Ejs.__name.call(void 0, knownPrimaryRootIds, "knownPrimaryRootIds");
|
|
38
56
|
async function refreshLockedRoots() {
|
|
39
|
-
const config =
|
|
57
|
+
const config = _chunkWUNSG3INjs.getOfflineConfig.call(void 0, );
|
|
40
58
|
if (!config.getUserId()) return;
|
|
41
|
-
const store = await
|
|
59
|
+
const store = await _chunkWUNSG3INjs.getOfflineStore.call(void 0, );
|
|
42
60
|
const now = /* @__PURE__ */ new Date();
|
|
43
61
|
const locked = [];
|
|
44
62
|
for (const id of await knownRootIds(store)) {
|
|
45
|
-
if (
|
|
63
|
+
if (_chunk6RCZ64BQjs.isRootLocked.call(void 0, await store.getSyncState(id), now)) locked.push(id);
|
|
46
64
|
}
|
|
47
|
-
|
|
65
|
+
_chunkWUNSG3INjs.setOfflineState.call(void 0, { lockedRootIds: locked });
|
|
48
66
|
}
|
|
49
67
|
_chunk7QVYU63Ejs.__name.call(void 0, refreshLockedRoots, "refreshLockedRoots");
|
|
50
68
|
|
|
@@ -97,9 +115,9 @@ async function updateLinks(store, typeConfig, record, before, after) {
|
|
|
97
115
|
if (!relationship || !("data" in relationship)) continue;
|
|
98
116
|
const next = new Map(identifiersOf(relationship).map((identifier) => [identifier.id, identifier]));
|
|
99
117
|
const previous = new Set(identifiersOf(_optionalChain([before, 'optionalAccess', _6 => _6[name]])).map((identifier) => identifier.id));
|
|
100
|
-
const kinds = _nullishCoalesce(
|
|
101
|
-
const ofRelationship = await
|
|
102
|
-
const mapped =
|
|
118
|
+
const kinds = _nullishCoalesce(_chunkN5ZE2Z6Ijs.linkKindsOf.call(void 0, typeConfig, name), () => ( [name]));
|
|
119
|
+
const ofRelationship = await _chunkN5ZE2Z6Ijs.linksOfKind.call(void 0, store, record.id, kinds, "both");
|
|
120
|
+
const mapped = _chunkN5ZE2Z6Ijs.linkKindsOf.call(void 0, typeConfig, name) !== void 0;
|
|
103
121
|
const stale = [
|
|
104
122
|
...ofRelationship.filter((link) => !next.has(otherEnd(link))),
|
|
105
123
|
// Unmapped: the link to an identifier the record held before may carry any kind.
|
|
@@ -107,7 +125,7 @@ async function updateLinks(store, typeConfig, record, before, after) {
|
|
|
107
125
|
];
|
|
108
126
|
for (const link of stale) await store.deleteLink({ fromId: link.fromId, toId: link.toId, kind: link.kind });
|
|
109
127
|
const linked = new Set(
|
|
110
|
-
(mapped ? await
|
|
128
|
+
(mapped ? await _chunkN5ZE2Z6Ijs.linksOfKind.call(void 0, store, record.id, kinds, "both") : await allLinks()).map(otherEnd)
|
|
111
129
|
);
|
|
112
130
|
for (const [id, identifier] of next) {
|
|
113
131
|
if (linked.has(id)) continue;
|
|
@@ -116,7 +134,7 @@ async function updateLinks(store, typeConfig, record, before, after) {
|
|
|
116
134
|
fromId: record.id,
|
|
117
135
|
toType: identifier.type,
|
|
118
136
|
toId: id,
|
|
119
|
-
kind:
|
|
137
|
+
kind: _chunkN5ZE2Z6Ijs.linkKindFor.call(void 0, typeConfig, name),
|
|
120
138
|
props: {}
|
|
121
139
|
});
|
|
122
140
|
}
|
|
@@ -124,13 +142,13 @@ async function updateLinks(store, typeConfig, record, before, after) {
|
|
|
124
142
|
}
|
|
125
143
|
_chunk7QVYU63Ejs.__name.call(void 0, updateLinks, "updateLinks");
|
|
126
144
|
async function storeResource(store, resource, pathRootId, waiting, kept, primary, images) {
|
|
127
|
-
const config =
|
|
145
|
+
const config = _chunkWUNSG3INjs.getOfflineConfig.call(void 0, );
|
|
128
146
|
if (!_optionalChain([resource, 'optionalAccess', _7 => _7.type]) || !_optionalChain([resource, 'optionalAccess', _8 => _8.id])) return;
|
|
129
147
|
if (!config.types.some((typeConfig) => typeConfig.module.name === resource.type)) return;
|
|
130
148
|
if (waiting.has(recordKeyOf(resource.type, resource.id))) return;
|
|
131
149
|
const existing = await store.getRecord(resource.type, resource.id);
|
|
132
150
|
if (existing && existing.base !== null) return;
|
|
133
|
-
const rootId = await _asyncNullishCoalesce(await _asyncNullishCoalesce(await _asyncOptionalChain([existing, 'optionalAccess', async _9 => _9.rootId]), async () => ( await
|
|
151
|
+
const rootId = await _asyncNullishCoalesce(await _asyncNullishCoalesce(await _asyncOptionalChain([existing, 'optionalAccess', async _9 => _9.rootId]), async () => ( await _chunkN5ZE2Z6Ijs.rootIdForResource.call(void 0, store, config, resource))), async () => ( pathRootId));
|
|
134
152
|
if (!rootId) return;
|
|
135
153
|
if (!kept.has(rootId)) return;
|
|
136
154
|
const before = _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _10 => _10.resource]), () => ( {}));
|
|
@@ -153,8 +171,8 @@ async function storeResource(store, resource, pathRootId, waiting, kept, primary
|
|
|
153
171
|
const typeConfig = config.types.find((candidate) => candidate.module.name === resource.type);
|
|
154
172
|
await updateLinks(store, typeConfig, resource, before.relationships, resource.relationships);
|
|
155
173
|
}
|
|
156
|
-
const url =
|
|
157
|
-
const previousUrl =
|
|
174
|
+
const url = _chunk6RCZ64BQjs.imageUrlOf.call(void 0, merged);
|
|
175
|
+
const previousUrl = _chunk6RCZ64BQjs.imageUrlOf.call(void 0, _optionalChain([existing, 'optionalAccess', _12 => _12.resource]));
|
|
158
176
|
if (url && url !== previousUrl) images.push({ url, previousUrl });
|
|
159
177
|
}
|
|
160
178
|
_chunk7QVYU63Ejs.__name.call(void 0, storeResource, "storeResource");
|
|
@@ -162,13 +180,13 @@ async function writeThrough(request, response) {
|
|
|
162
180
|
const method = request.method.toUpperCase();
|
|
163
181
|
if (method === "GET" || !response.ok) return;
|
|
164
182
|
try {
|
|
165
|
-
const config =
|
|
183
|
+
const config = _chunkWUNSG3INjs.getOfflineConfig.call(void 0, );
|
|
166
184
|
if (!config.getUserId()) return;
|
|
167
|
-
const { path } =
|
|
168
|
-
const store = await
|
|
185
|
+
const { path } = _chunkN5ZE2Z6Ijs.splitApiUrl.call(void 0, request.url);
|
|
186
|
+
const store = await _chunkWUNSG3INjs.getOfflineStore.call(void 0, );
|
|
169
187
|
if (method === "DELETE") {
|
|
170
188
|
for (const typeConfig of config.types) {
|
|
171
|
-
const params =
|
|
189
|
+
const params = _chunkN5ZE2Z6Ijs.matchPattern.call(void 0, [typeConfig.module, ":id"], path);
|
|
172
190
|
if (params) {
|
|
173
191
|
await store.deleteRecord(typeConfig.module.name, params.id);
|
|
174
192
|
return;
|
|
@@ -176,8 +194,8 @@ async function writeThrough(request, response) {
|
|
|
176
194
|
}
|
|
177
195
|
return;
|
|
178
196
|
}
|
|
179
|
-
const
|
|
180
|
-
const pathRootId = _optionalChain([
|
|
197
|
+
const rootSegments = path.split("/").slice(0, 2).join("/");
|
|
198
|
+
const pathRootId = _chunkWUNSG3INjs.rootKinds.call(void 0, config).map((kind) => _optionalChain([_chunkN5ZE2Z6Ijs.matchPattern.call(void 0, [kind.module, ":rootId"], rootSegments), 'optionalAccess', _13 => _13.rootId])).find((rootId) => rootId !== void 0);
|
|
181
199
|
const document = response.data;
|
|
182
200
|
const primary = Array.isArray(_optionalChain([document, 'optionalAccess', _14 => _14.data])) ? document.data : _optionalChain([document, 'optionalAccess', _15 => _15.data]) ? [document.data] : [];
|
|
183
201
|
const waiting = waitingRecordKeys(
|
|
@@ -194,9 +212,9 @@ async function writeThrough(request, response) {
|
|
|
194
212
|
await storeResource(transactionStore, resource, pathRootId, waiting, kept, false, images);
|
|
195
213
|
}
|
|
196
214
|
});
|
|
197
|
-
for (const image of images) await
|
|
215
|
+
for (const image of images) await _chunk6RCZ64BQjs.cacheArtworkImage.call(void 0, image.url, image.previousUrl);
|
|
198
216
|
} catch (error) {
|
|
199
|
-
if (error instanceof
|
|
217
|
+
if (error instanceof _chunkWUNSG3INjs.OfflineUnavailableError) return;
|
|
200
218
|
console.warn("[offline] could not copy the answer to the device", error);
|
|
201
219
|
}
|
|
202
220
|
}
|
|
@@ -210,5 +228,6 @@ _chunk7QVYU63Ejs.__name.call(void 0, writeThrough, "writeThrough");
|
|
|
210
228
|
|
|
211
229
|
|
|
212
230
|
|
|
213
|
-
|
|
214
|
-
|
|
231
|
+
|
|
232
|
+
exports.rememberSyncRoots = rememberSyncRoots; exports.knownRootIds = knownRootIds; exports.knownPrimaryRootIds = knownPrimaryRootIds; exports.refreshLockedRoots = refreshLockedRoots; exports.recordKeyOf = recordKeyOf; exports.recordKeysOfEntry = recordKeysOfEntry; exports.waitingRecordKeys = waitingRecordKeys; exports.writeThrough = writeThrough;
|
|
233
|
+
//# sourceMappingURL=chunk-QGVVF77L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-QGVVF77L.js","../src/offline/sync/known-roots.ts","../src/offline/sync/waiting.ts","../src/offline/write-through.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACF,sDAA4B;AAC5B;AACA;ACnBA,IAAI,eAAA,EAA2B,CAAC,CAAA;AAChC,IAAI,oBAAA,EAAgC,CAAC,CAAA;AAM9B,SAAS,iBAAA,CAAkB,GAAA,EAAe,SAAA,EAAqB,CAAC,CAAA,EAAS;AAC9E,EAAA,eAAA,EAAiB,CAAC,GAAG,GAAG,CAAA;AACxB,EAAA,oBAAA,EAAsB,CAAC,GAAG,QAAQ,CAAA;AACpC;AAHgB,qCAAA,iBAAA,EAAA,mBAAA,CAAA;AAUhB,MAAA,SAAsB,YAAA,CAAa,KAAA,EAAuC;AACxE,EAAA,MAAM,OAAA,EAAS,+CAAA,CAAiB;AAChC,EAAA,MAAM,IAAA,EAAM,IAAI,GAAA,CAAY,cAAc,CAAA;AAC1C,EAAA,IAAA,CAAA,MAAW,KAAA,GAAQ,wCAAA,MAAgB,CAAA,EAAG;AACpC,IAAA,IAAA,CAAA,MAAW,OAAA,GAAU,MAAM,KAAA,CAAM,WAAA,CAAY,EAAE,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AAAA,EAC7F;AACA,EAAA,IAAA,CAAA,MAAW,MAAA,GAAS,MAAM,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA;AAC7D,EAAA,OAAO,CAAC,GAAG,GAAG,CAAA,CAAE,IAAA,CAAK,CAAA;AACvB;AARsB,qCAAA,YAAA,EAAA,cAAA,CAAA;AAWtB,MAAA,SAAe,YAAA,CAAa,KAAA,EAA0C;AACpE,EAAA,MAAM,IAAA,EAAM,IAAI,GAAA,CAAY,mBAAmB,CAAA;AAC/C,EAAA,IAAA,CAAA,MAAW,KAAA,oBAAQ,+CAAA,CAAiB,CAAE,cAAA,UAAkB,CAAC,GAAA,EAAG;AAC1D,IAAA,IAAA,CAAA,MAAW,OAAA,GAAU,MAAM,KAAA,CAAM,WAAA,CAAY,EAAE,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AAAA,EAC7F;AACA,EAAA,OAAO,GAAA;AACT;AANe,qCAAA,YAAA,EAAA,cAAA,CAAA;AASf,MAAA,SAAsB,mBAAA,CAAoB,KAAA,EAAuC;AAC/E,EAAA,MAAM,MAAA,EAAQ,MAAM,YAAA,CAAa,KAAK,CAAA;AACtC,EAAA,OAAA,CAAQ,MAAM,YAAA,CAAa,KAAK,CAAA,CAAA,CAAG,MAAA,CAAO,CAAC,EAAA,EAAA,GAAO,CAAC,KAAA,CAAM,GAAA,CAAI,EAAE,CAAC,CAAA;AAClE;AAHsB,qCAAA,mBAAA,EAAA,qBAAA,CAAA;AAMtB,MAAA,SAAsB,kBAAA,CAAA,EAAoC;AACxD,EAAA,MAAM,OAAA,EAAS,+CAAA,CAAiB;AAChC,EAAA,GAAA,CAAI,CAAC,MAAA,CAAO,SAAA,CAAU,CAAA,EAAG,MAAA;AACzB,EAAA,MAAM,MAAA,EAAQ,MAAM,8CAAA,CAAgB;AACpC,EAAA,MAAM,IAAA,kBAAM,IAAI,IAAA,CAAK,CAAA;AACrB,EAAA,MAAM,OAAA,EAAmB,CAAC,CAAA;AAC1B,EAAA,IAAA,CAAA,MAAW,GAAA,GAAM,MAAM,YAAA,CAAa,KAAK,CAAA,EAAG;AAC1C,IAAA,GAAA,CAAI,2CAAA,MAAmB,KAAA,CAAM,YAAA,CAAa,EAAE,CAAA,EAAG,GAAG,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAAA,EACrE;AACA,EAAA,8CAAA,EAAkB,aAAA,EAAe,OAAO,CAAC,CAAA;AAC3C;AAVsB,qCAAA,kBAAA,EAAA,oBAAA,CAAA;ADmBtB;AACA;AElEO,IAAM,YAAA,kBAAc,qCAAA,CAAC,IAAA,EAAc,EAAA,EAAA,GAAe,CAAA,EAAA;AAQ8B;AAC7D,EAAA;AAC0B,EAAA;AAEzB,EAAA;AACuB,EAAA;AACL,IAAA;AAC3C,EAAA;AAGe,EAAA;AAGmC,EAAA;AACX,IAAA;AACM,IAAA;AAC3C,IAAA;AACF,EAAA;AACO,EAAA;AACT;AAnBgB;AAyB4E;AAC7D,EAAA;AACgB,EAAA;AACtC,EAAA;AACT;AAJgB;AFyDwC;AACA;AGhFP;AACX,EAAA;AACjB,EAAA;AACQ,EAAA;AACkB,EAAA;AAC/C;AALS;AAS+C;AAC3B,EAAA;AACR,EAAA;AACkC,EAAA;AACvD;AAJS;AAiBP;AAGwC,EAAA;AACY,EAAA;AACf,IAAA;AACF,IAAA;AAFlB,EAAA;AAKsC,EAAA;AACL,IAAA;AACC,IAAA;AACG,IAAA;AACA,IAAA;AACJ,IAAA;AACC,IAAA;AAEnC,IAAA;AACiC,MAAA;AAAe;AAEf,MAAA;AAC/C,IAAA;AACmD,IAAA;AAEhC,IAAA;AAC6B,MAAA;AAChD,IAAA;AACqC,IAAA;AACf,MAAA;AACA,MAAA;AACD,QAAA;AACF,QAAA;AACI,QAAA;AACb,QAAA;AAC4B,QAAA;AAC1B,QAAA;AACT,MAAA;AACH,IAAA;AACF,EAAA;AACF;AA3Ce;AAkDb;AAMgC,EAAA;AACM,EAAA;AACY,EAAA;AAGI,EAAA;AAEA,EAAA;AACd,EAAA;AACE,EAAA;AAE7B,EAAA;AAEU,EAAA;AAGe,EAAA;AACvB,EAAA;AACV,IAAA;AACA,IAAA;AAC6C,IAAA;AACM,IAAA;AACxD,EAAA;AAEsB,EAAA;AACL,IAAA;AACF,IAAA;AACb,IAAA;AACU,IAAA;AACoC,IAAA;AACxC,IAAA;AACK,IAAA;AACZ,EAAA;AACY,EAAA;AACyC,IAAA;AACL,IAAA;AACjD,EAAA;AAE6B,EAAA;AACoB,EAAA;AACE,EAAA;AACrD;AAlDe;AAyDoF;AACvD,EAAA;AACJ,EAAA;AAElC,EAAA;AAC8B,IAAA;AACP,IAAA;AACe,IAAA;AACJ,IAAA;AAEX,IAAA;AACgB,MAAA;AACW,QAAA;AACpC,QAAA;AACiC,UAAA;AAC3C,UAAA;AACF,QAAA;AACF,MAAA;AACA,MAAA;AACF,IAAA;AAGiD,IAAA;AAEhC,IAAA;AAGS,IAAA;AACsB,IAAA;AAChC,IAAA;AACI,MAAA;AACuB,MAAA;AAC3C,IAAA;AAG8C,IAAA;AACf,IAAA;AACqB,IAAA;AAClB,MAAA;AACkB,QAAA;AAClD,MAAA;AACiD,MAAA;AACC,QAAA;AAClD,MAAA;AACD,IAAA;AAEmD,IAAA;AACtC,EAAA;AAEgC,IAAA;AACjC,IAAA;AACf,EAAA;AACF;AApDsB;AHkFkC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-QGVVF77L.js","sourcesContent":[null,"import { getOfflineConfig, getOfflineStore, rootKinds } from \"../config\";\nimport { setOfflineState } from \"../state\";\nimport type { DeviceStore } from \"../store/DeviceStore\";\nimport { isRootLocked } from \"../store/lifecycle\";\n\nlet _lastSyncRoots: string[] = [];\nlet _lastExtraSyncRoots: string[] = [];\n\n/**\n * Remembers the root records the last online sync listed: `ids` of every kind, `extraIds` those\n * of the `extraRootKinds` among them.\n */\nexport function rememberSyncRoots(ids: string[], extraIds: string[] = []): void {\n _lastSyncRoots = [...ids];\n _lastExtraSyncRoots = [...extraIds];\n}\n\n/**\n * Every root record the device knows of, of every kind: its stored root records, the root records\n * with waiting changes, and the last sync roots (a locked root record is never downloaded, so it\n * may have no stored record).\n */\nexport async function knownRootIds(store: DeviceStore): Promise<string[]> {\n const config = getOfflineConfig();\n const ids = new Set<string>(_lastSyncRoots);\n for (const kind of rootKinds(config)) {\n for (const record of await store.listRecords({ type: kind.module.name })) ids.add(record.id);\n }\n for (const entry of await store.queue()) ids.add(entry.rootId);\n return [...ids].sort();\n}\n\n/** The known root records of the `extraRootKinds`: stored, or listed by the last sync. */\nasync function extraRootIds(store: DeviceStore): Promise<Set<string>> {\n const ids = new Set<string>(_lastExtraSyncRoots);\n for (const kind of getOfflineConfig().extraRootKinds ?? []) {\n for (const record of await store.listRecords({ type: kind.module.name })) ids.add(record.id);\n }\n return ids;\n}\n\n/** `knownRootIds` without the root records of the `extraRootKinds` (the primary kind only). */\nexport async function knownPrimaryRootIds(store: DeviceStore): Promise<string[]> {\n const extra = await extraRootIds(store);\n return (await knownRootIds(store)).filter((id) => !extra.has(id));\n}\n\n/** Recomputes `lockedRootIds` from the stored sync states, now. */\nexport async function refreshLockedRoots(): Promise<void> {\n const config = getOfflineConfig();\n if (!config.getUserId()) return;\n const store = await getOfflineStore();\n const now = new Date();\n const locked: string[] = [];\n for (const id of await knownRootIds(store)) {\n if (isRootLocked(await store.getSyncState(id), now)) locked.push(id);\n }\n setOfflineState({ lockedRootIds: locked });\n}\n","import type { QueueEntry } from \"../store/DeviceStore\";\n\nexport const recordKeyOf = (type: string, id: string) => `${type}:${id}`;\n\n/**\n * The records a queue entry targets: its `recordType`/`recordId`, the `data.type`/`data.id` of\n * its body (a record created on this device), and the `<type>/<id>` of its path (the last\n * segment naming a synced type, when an id follows it: `npcs/n1`, `npcs/n1/merge`; a collection\n * path such as `roots/C/npcs` targets no record).\n */\nexport function recordKeysOfEntry(entry: QueueEntry, typeNames: Set<string>): string[] {\n const keys: string[] = [];\n if (entry.recordType && entry.recordId) keys.push(recordKeyOf(entry.recordType, entry.recordId));\n\n const data = entry.body?.data;\n if (data && !Array.isArray(data) && typeof data.type === \"string\" && typeof data.id === \"string\") {\n keys.push(recordKeyOf(data.type, data.id));\n }\n\n const segments = String(entry.path ?? \"\")\n .split(\"?\")[0]\n .split(\"/\")\n .filter(Boolean);\n for (let index = segments.length - 1; index >= 0; index--) {\n if (!typeNames.has(segments[index])) continue;\n if (index + 1 < segments.length) keys.push(recordKeyOf(segments[index], segments[index + 1]));\n break;\n }\n return keys;\n}\n\n/**\n * Every record with a waiting change: targeted by a queue entry that is pending, sending, in\n * conflict or failed. Such a record is never overwritten or deleted by a sync or a write-through.\n */\nexport function waitingRecordKeys(queue: QueueEntry[], typeNames: Set<string>): Set<string> {\n const keys = new Set<string>();\n for (const entry of queue) for (const key of recordKeysOfEntry(entry, typeNames)) keys.add(key);\n return keys;\n}\n","import type { ApiData } from \"../core/interfaces/ApiData\";\nimport { getOfflineConfig, getOfflineStore, OfflineUnavailableError, rootKinds } from \"./config\";\nimport { rootIdForResource, linkKindFor, linkKindsOf, linksOfKind } from \"./generic-answers\";\nimport { splitApiUrl } from \"./local-transport\";\nimport { matchPattern } from \"./router\";\nimport type { DeviceStore, StoredLink } from \"./store/DeviceStore\";\nimport type { OfflineTypeConfig } from \"./types\";\nimport { cacheArtworkImage, imageUrlOf } from \"./sync/artwork-cache\";\nimport { knownRootIds } from \"./sync/known-roots\";\nimport { recordKeyOf, waitingRecordKeys } from \"./sync/waiting\";\n\nexport type WriteThroughRequest = { method: string; url: string };\n\nfunction updatedAtOf(resource: any): Date | null {\n const value = resource?.attributes?.updatedAt;\n if (!value) return null;\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? null : date;\n}\n\ntype Identifier = { type: string; id: string };\n\nfunction identifiersOf(relationship: any): Identifier[] {\n const data = relationship?.data;\n if (!data) return [];\n return (Array.isArray(data) ? data : [data]).filter((item: any) => item && item.type && item.id);\n}\n\n/**\n * Brings the stored links of the written record in line with the relationships the answer\n * carries (only those whose `data` it holds), as the local answers do: a link of the\n * relationship (its name or mapped Neo4j type; any kind when the type is not mapped, for an\n * identifier the record held before) to an identifier no longer there is removed, and a new\n * identifier gets a link of `linkKindFor` the relationship.\n */\nasync function updateLinks(\n store: DeviceStore,\n typeConfig: OfflineTypeConfig | undefined,\n record: Identifier,\n before: any,\n after: any,\n): Promise<void> {\n const otherEnd = (link: StoredLink) => (link.fromId === record.id ? link.toId : link.fromId);\n const allLinks = async (): Promise<StoredLink[]> => [\n ...(await store.linksFrom(record.id)),\n ...(await store.linksTo(record.id)),\n ];\n\n for (const [name, relationship] of Object.entries<any>(after ?? {})) {\n if (!relationship || !(\"data\" in relationship)) continue;\n const next = new Map(identifiersOf(relationship).map((identifier) => [identifier.id, identifier]));\n const previous = new Set(identifiersOf(before?.[name]).map((identifier) => identifier.id));\n const kinds = linkKindsOf(typeConfig, name) ?? [name];\n const ofRelationship = await linksOfKind(store, record.id, kinds, \"both\");\n const mapped = linkKindsOf(typeConfig, name) !== undefined;\n\n const stale = [\n ...ofRelationship.filter((link) => !next.has(otherEnd(link))),\n // Unmapped: the link to an identifier the record held before may carry any kind.\n ...(mapped ? [] : (await allLinks()).filter((link) => previous.has(otherEnd(link)) && !next.has(otherEnd(link)))),\n ];\n for (const link of stale) await store.deleteLink({ fromId: link.fromId, toId: link.toId, kind: link.kind });\n\n const linked = new Set(\n (mapped ? await linksOfKind(store, record.id, kinds, \"both\") : await allLinks()).map(otherEnd),\n );\n for (const [id, identifier] of next) {\n if (linked.has(id)) continue;\n await store.putLink({\n fromType: record.type,\n fromId: record.id,\n toType: identifier.type,\n toId: id,\n kind: linkKindFor(typeConfig, name),\n props: {},\n });\n }\n }\n}\n\ntype ImageChange = { url: string; previousUrl?: string };\n\nasync function storeResource(\n store: DeviceStore,\n resource: any,\n pathRootId: string | undefined,\n waiting: Set<string>,\n kept: Set<string>,\n primary: boolean,\n images: ImageChange[],\n): Promise<void> {\n const config = getOfflineConfig();\n if (!resource?.type || !resource?.id) return;\n if (!config.types.some((typeConfig) => typeConfig.module.name === resource.type)) return;\n // A record with unsent local changes keeps them: the next sync, once they are sent, brings\n // the server's version.\n if (waiting.has(recordKeyOf(resource.type, resource.id))) return;\n\n const existing = await store.getRecord(resource.type, resource.id);\n if (existing && existing.base !== null) return;\n const rootId = existing?.rootId ?? (await rootIdForResource(store, config, resource)) ?? pathRootId;\n // A record that belongs to no root record on this device waits for the next sync.\n if (!rootId) return;\n // Only the root records the device keeps are written through (never a player's root record).\n if (!kept.has(rootId)) return;\n\n // An answer can carry a sparse resource (fields limited): it is merged onto what is stored.\n const before = existing?.resource ?? {};\n const merged = {\n ...before,\n ...resource,\n attributes: { ...(before.attributes ?? {}), ...(resource.attributes ?? {}) },\n relationships: { ...(before.relationships ?? {}), ...(resource.relationships ?? {}) },\n };\n\n await store.putRecord({\n type: resource.type,\n id: resource.id,\n rootId,\n resource: merged,\n updatedAt: updatedAtOf(resource) ?? existing?.updatedAt ?? null,\n base: null,\n localOnly: false,\n });\n if (primary) {\n const typeConfig = config.types.find((candidate) => candidate.module.name === resource.type);\n await updateLinks(store, typeConfig, resource, before.relationships, resource.relationships);\n }\n\n const url = imageUrlOf(merged);\n const previousUrl = imageUrlOf(existing?.resource);\n if (url && url !== previousUrl) images.push({ url, previousUrl });\n}\n\n/**\n * After a successful online write, copies the answer into the device copy so it is never behind\n * the GM's own work: the resource and its `included` for POST/PUT/PATCH, the record removed for a\n * DELETE. It never fails the request: a problem is logged and the next sync repairs the copy.\n */\nexport async function writeThrough(request: WriteThroughRequest, response: ApiData): Promise<void> {\n const method = request.method.toUpperCase();\n if (method === \"GET\" || !response.ok) return;\n\n try {\n const config = getOfflineConfig();\n if (!config.getUserId()) return;\n const { path } = splitApiUrl(request.url);\n const store = await getOfflineStore();\n\n if (method === \"DELETE\") {\n for (const typeConfig of config.types) {\n const params = matchPattern([typeConfig.module, \":id\"], path);\n if (params) {\n await store.deleteRecord(typeConfig.module.name, params.id);\n return;\n }\n }\n return;\n }\n\n // A path under a root record of any kind (`<root module>/:rootId/...`).\n const rootSegments = path.split(\"/\").slice(0, 2).join(\"/\");\n const pathRootId = rootKinds(config)\n .map((kind) => matchPattern([kind.module, \":rootId\"], rootSegments)?.rootId)\n .find((rootId) => rootId !== undefined);\n\n const document = response.data;\n const primary = Array.isArray(document?.data) ? document.data : document?.data ? [document.data] : [];\n const waiting = waitingRecordKeys(\n await store.queue(),\n new Set(config.types.map((typeConfig) => typeConfig.module.name)),\n );\n // The root records this device keeps for the signed-in user (stored roots, waiting changes, last\n // sync roots): a write in any other root record (a player's) stores nothing.\n const kept = new Set(await knownRootIds(store));\n const images: ImageChange[] = [];\n await store.transaction(async (transactionStore) => {\n for (const resource of primary) {\n await storeResource(transactionStore, resource, pathRootId, waiting, kept, true, images);\n }\n for (const resource of document?.included ?? []) {\n await storeResource(transactionStore, resource, pathRootId, waiting, kept, false, images);\n }\n });\n // A new image URL of an artwork: downloaded, the old cached image removed (as the sync does).\n for (const image of images) await cacheArtworkImage(image.url, image.previousUrl);\n } catch (error) {\n // A browser that cannot keep the device copy was already warned about once.\n if (error instanceof OfflineUnavailableError) return;\n console.warn(\"[offline] could not copy the answer to the device\", error);\n }\n}\n"]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
ENV,
|
|
9
9
|
JsonApiDataFactory,
|
|
10
10
|
translateResponse
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MQ7TXALH.mjs";
|
|
12
12
|
import {
|
|
13
13
|
__name
|
|
14
14
|
} from "./chunk-PAWJFY3S.mjs";
|
|
@@ -201,4 +201,4 @@ export {
|
|
|
201
201
|
ServerJsonApiPatch,
|
|
202
202
|
ServerJsonApiDelete
|
|
203
203
|
};
|
|
204
|
-
//# sourceMappingURL=chunk-
|
|
204
|
+
//# sourceMappingURL=chunk-QIEF7HIL.mjs.map
|
|
@@ -8,20 +8,20 @@ import {
|
|
|
8
8
|
getI18nDefaultLocale,
|
|
9
9
|
getI18nServerLocale,
|
|
10
10
|
getI18nSupportedLocales
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-UOTHRJD2.mjs";
|
|
12
12
|
import {
|
|
13
13
|
ClientJsonApiDelete,
|
|
14
14
|
ClientJsonApiGet,
|
|
15
15
|
ClientJsonApiPatch,
|
|
16
16
|
ClientJsonApiPost,
|
|
17
17
|
ClientJsonApiPut
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-AUD6ZLBB.mjs";
|
|
19
19
|
import {
|
|
20
20
|
DataClassRegistry,
|
|
21
21
|
JsonApiDelete,
|
|
22
22
|
JsonApiGet,
|
|
23
23
|
JsonApiPost
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-MQ7TXALH.mjs";
|
|
25
25
|
import {
|
|
26
26
|
__name
|
|
27
27
|
} from "./chunk-PAWJFY3S.mjs";
|
|
@@ -119,7 +119,7 @@ var AbstractService = class {
|
|
|
119
119
|
* Make an API call with automatic environment detection and error handling.
|
|
120
120
|
*/
|
|
121
121
|
static async callApi(params) {
|
|
122
|
-
const { JsonApiGet: JsonApiGet2, JsonApiPost: JsonApiPost2, JsonApiPut, JsonApiPatch, JsonApiDelete: JsonApiDelete2 } = await import("./JsonApiRequest-
|
|
122
|
+
const { JsonApiGet: JsonApiGet2, JsonApiPost: JsonApiPost2, JsonApiPut, JsonApiPatch, JsonApiDelete: JsonApiDelete2 } = await import("./JsonApiRequest-IKKHWCPB.mjs");
|
|
123
123
|
let apiResponse;
|
|
124
124
|
let language = "en";
|
|
125
125
|
if (typeof window === "undefined") {
|
|
@@ -216,7 +216,7 @@ var AbstractService = class {
|
|
|
216
216
|
* Make an API call and return both data and meta from the response.
|
|
217
217
|
*/
|
|
218
218
|
static async callApiWithMeta(params) {
|
|
219
|
-
const { JsonApiGet: JsonApiGet2, JsonApiPost: JsonApiPost2, JsonApiPut, JsonApiPatch, JsonApiDelete: JsonApiDelete2 } = await import("./JsonApiRequest-
|
|
219
|
+
const { JsonApiGet: JsonApiGet2, JsonApiPost: JsonApiPost2, JsonApiPut, JsonApiPatch, JsonApiDelete: JsonApiDelete2 } = await import("./JsonApiRequest-IKKHWCPB.mjs");
|
|
220
220
|
let apiResponse;
|
|
221
221
|
let language = "en";
|
|
222
222
|
if (typeof window === "undefined") {
|
|
@@ -301,7 +301,7 @@ var AbstractService = class {
|
|
|
301
301
|
* Get raw JSON:API response data without deserialization.
|
|
302
302
|
*/
|
|
303
303
|
static async getRawData(params) {
|
|
304
|
-
const { JsonApiGet: JsonApiGet2 } = await import("./JsonApiRequest-
|
|
304
|
+
const { JsonApiGet: JsonApiGet2 } = await import("./JsonApiRequest-IKKHWCPB.mjs");
|
|
305
305
|
let language = "en";
|
|
306
306
|
if (typeof window === "undefined") {
|
|
307
307
|
language = await getI18nServerLocale();
|
|
@@ -12636,4 +12636,4 @@ export {
|
|
|
12636
12636
|
AuditLogService,
|
|
12637
12637
|
AuditLogModule
|
|
12638
12638
|
};
|
|
12639
|
-
//# sourceMappingURL=chunk-
|
|
12639
|
+
//# sourceMappingURL=chunk-RFKSJIQB.mjs.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
DataClassRegistry,
|
|
3
3
|
hasBootstrapper,
|
|
4
4
|
tryBootstrap
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MQ7TXALH.mjs";
|
|
6
6
|
import {
|
|
7
7
|
__name
|
|
8
8
|
} from "./chunk-PAWJFY3S.mjs";
|
|
@@ -567,4 +567,4 @@ export {
|
|
|
567
567
|
ROOT_SYNC_ENDPOINT,
|
|
568
568
|
RootSync
|
|
569
569
|
};
|
|
570
|
-
//# sourceMappingURL=chunk-
|
|
570
|
+
//# sourceMappingURL=chunk-UOTHRJD2.mjs.map
|
|
@@ -4,24 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkWUNSG3INjs = require('./chunk-WUNSG3IN.js');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
var _chunk7QVYU63Ejs = require('./chunk-7QVYU63E.js');
|
|
11
11
|
|
|
12
12
|
// src/client/request.ts
|
|
13
13
|
async function directFetch(params) {
|
|
14
|
-
const offline =
|
|
15
|
-
if (offline && !
|
|
14
|
+
const offline = _chunkWUNSG3INjs.isOfflineConfigured.call(void 0, ) && !hasReplayHeader(params.additionalHeaders);
|
|
15
|
+
if (offline && !_chunkWUNSG3INjs.getOfflineState.call(void 0, ).online && !_chunkWUNSG3INjs.reachesNetworkWhileOffline.call(void 0, params.method, params.url)) {
|
|
16
16
|
return answerLocally(params);
|
|
17
17
|
}
|
|
18
18
|
const response = await fetchFromApi(params);
|
|
19
19
|
if (offline && response.networkError) {
|
|
20
|
-
|
|
20
|
+
_chunkWUNSG3INjs.setOfflineState.call(void 0, { online: false });
|
|
21
21
|
return answerLocally(params);
|
|
22
22
|
}
|
|
23
23
|
if (offline && response.ok && params.method.toUpperCase() !== "GET") {
|
|
24
|
-
const { writeThrough } = await Promise.resolve().then(() => _interopRequireWildcard(require("./write-through-
|
|
24
|
+
const { writeThrough } = await Promise.resolve().then(() => _interopRequireWildcard(require("./write-through-BAPS24GL.js")));
|
|
25
25
|
await writeThrough({ method: params.method, url: params.url }, response);
|
|
26
26
|
}
|
|
27
27
|
return response;
|
|
@@ -29,11 +29,11 @@ async function directFetch(params) {
|
|
|
29
29
|
_chunk7QVYU63Ejs.__name.call(void 0, directFetch, "directFetch");
|
|
30
30
|
function hasReplayHeader(headers) {
|
|
31
31
|
if (!headers) return false;
|
|
32
|
-
return Object.keys(headers).some((key) => key.toLowerCase() ===
|
|
32
|
+
return Object.keys(headers).some((key) => key.toLowerCase() === _chunkWUNSG3INjs.OFFLINE_REPLAY_HEADER);
|
|
33
33
|
}
|
|
34
34
|
_chunk7QVYU63Ejs.__name.call(void 0, hasReplayHeader, "hasReplayHeader");
|
|
35
35
|
async function answerLocally(params) {
|
|
36
|
-
const { localTransport } = await Promise.resolve().then(() => _interopRequireWildcard(require("./local-transport-
|
|
36
|
+
const { localTransport } = await Promise.resolve().then(() => _interopRequireWildcard(require("./local-transport-4YDJ6FQG.js")));
|
|
37
37
|
return localTransport({ method: params.method, url: params.url, body: params.body, files: params.files });
|
|
38
38
|
}
|
|
39
39
|
_chunk7QVYU63Ejs.__name.call(void 0, answerLocally, "answerLocally");
|
|
@@ -110,4 +110,4 @@ _chunk7QVYU63Ejs.__name.call(void 0, fetchFromApi, "fetchFromApi");
|
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
exports.directFetch = directFetch;
|
|
113
|
-
//# sourceMappingURL=chunk-
|
|
113
|
+
//# sourceMappingURL=chunk-WCEYT3GG.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-WCEYT3GG.js","../src/client/request.ts"],"names":[],"mappings":"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","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-WCEYT3GG.js","sourcesContent":[null,"\"use client\";\n\nimport { ApiData } from \"../core/interfaces/ApiData\";\nimport { isOfflineConfigured } from \"../offline/config\";\nimport { getOfflineState, reachesNetworkWhileOffline, setOfflineState } from \"../offline/state\";\nimport { OFFLINE_REPLAY_HEADER } from \"../offline/types\";\n\nexport interface DirectFetchParams {\n method: string;\n url: string;\n token?: string;\n body?: any;\n files?: { [key: string]: File | Blob } | File | Blob;\n companyId?: string;\n language: string;\n additionalHeaders?: Record<string, string>;\n}\n\n/**\n * Client-side direct fetch to bypass server action overhead.\n * Use this for client-side API calls.\n */\nexport async function directFetch(params: DirectFetchParams): Promise<ApiData> {\n // Offline mode is opt-in (`configureOffline`). Without it nothing below loads or runs. A request\n // the server runs as an offline replay always goes to the network, and so do the reads and the\n // change-set request of a reconnect attempt (the session stays offline until its sync succeeds).\n const offline = isOfflineConfigured() && !hasReplayHeader(params.additionalHeaders);\n if (offline && !getOfflineState().online && !reachesNetworkWhileOffline(params.method, params.url)) {\n return answerLocally(params);\n }\n\n const response = await fetchFromApi(params);\n\n if (offline && response.networkError) {\n setOfflineState({ online: false });\n return answerLocally(params);\n }\n if (offline && response.ok && params.method.toUpperCase() !== \"GET\") {\n const { writeThrough } = await import(\"../offline/write-through\");\n await writeThrough({ method: params.method, url: params.url }, response);\n }\n\n return response;\n}\n\nfunction hasReplayHeader(headers?: Record<string, string>): boolean {\n if (!headers) return false;\n return Object.keys(headers).some((key) => key.toLowerCase() === OFFLINE_REPLAY_HEADER);\n}\n\nasync function answerLocally(params: DirectFetchParams): Promise<ApiData> {\n const { localTransport } = await import(\"../offline/local-transport\");\n return localTransport({ method: params.method, url: params.url, body: params.body, files: params.files });\n}\n\nasync function fetchFromApi(params: DirectFetchParams): Promise<ApiData> {\n const response: ApiData = {\n data: undefined,\n ok: false,\n status: 0,\n statusText: \"\",\n };\n\n const additionalHeaders: Record<string, string> = { ...params.additionalHeaders };\n\n if (params.companyId) {\n additionalHeaders[\"x-companyid\"] = params.companyId;\n }\n additionalHeaders[\"x-language\"] = params.language;\n\n let requestBody: BodyInit | undefined = undefined;\n\n if (params.files) {\n const formData = new FormData();\n if (params.body && typeof params.body === \"object\") {\n for (const key in params.body) {\n if (Object.prototype.hasOwnProperty.call(params.body, key)) {\n formData.append(\n key,\n typeof params.body[key] === \"object\" ? JSON.stringify(params.body[key]) : params.body[key],\n );\n }\n }\n }\n\n if (params.files instanceof Blob) {\n formData.append(\"file\", params.files);\n } else if (typeof params.files === \"object\" && params.files !== null) {\n for (const key in params.files) {\n if (Object.prototype.hasOwnProperty.call(params.files, key)) {\n formData.append(key, params.files[key]);\n }\n }\n }\n\n requestBody = formData;\n } else if (params.body !== undefined) {\n requestBody = JSON.stringify(params.body);\n additionalHeaders[\"Content-Type\"] = \"application/json\";\n }\n\n const options: RequestInit = {\n method: params.method,\n headers: { Accept: \"application/json\", ...additionalHeaders },\n };\n\n if (requestBody !== undefined) {\n options.body = requestBody;\n }\n\n if (params.token) {\n options.headers = { ...options.headers, Authorization: `Bearer ${params.token}` };\n }\n\n try {\n const apiResponse = await fetch(params.url, options);\n\n response.ok = apiResponse.ok;\n response.status = apiResponse.status;\n response.statusText = apiResponse.statusText;\n try {\n response.data = await apiResponse.json();\n } catch {\n response.data = undefined;\n }\n } catch {\n // fetch() only throws when the API could not be reached at all (server\n // down, DNS, connection refused). Report it as 503 so consumers can tell\n // \"API unreachable\" apart from a 500 the API actually returned.\n response.ok = false;\n response.status = 503;\n response.statusText = \"Service Unavailable\";\n response.data = undefined;\n response.networkError = true;\n }\n\n return response;\n}\n"]}
|
|
@@ -225,6 +225,10 @@ function refreshOfflineDeviceState() {
|
|
|
225
225
|
});
|
|
226
226
|
}
|
|
227
227
|
_chunk7QVYU63Ejs.__name.call(void 0, refreshOfflineDeviceState, "refreshOfflineDeviceState");
|
|
228
|
+
function rootKinds(config) {
|
|
229
|
+
return [{ module: config.rootModule, listSyncRoots: config.listSyncRoots }, ..._nullishCoalesce(config.extraRootKinds, () => ( []))];
|
|
230
|
+
}
|
|
231
|
+
_chunk7QVYU63Ejs.__name.call(void 0, rootKinds, "rootKinds");
|
|
228
232
|
function getOfflineConfig() {
|
|
229
233
|
if (!_config) throw new Error("Offline mode is not configured. Call configureOffline() first.");
|
|
230
234
|
return _config;
|
|
@@ -313,5 +317,6 @@ _chunk7QVYU63Ejs.__name.call(void 0, forgetOfflineStore, "forgetOfflineStore");
|
|
|
313
317
|
|
|
314
318
|
|
|
315
319
|
|
|
316
|
-
|
|
317
|
-
|
|
320
|
+
|
|
321
|
+
exports.SERVER_SNAPSHOT = SERVER_SNAPSHOT; exports.getOfflineState = getOfflineState; exports.subscribeOfflineState = subscribeOfflineState; exports.isReconnecting = isReconnecting; exports.setReconnecting = setReconnecting; exports.allowWhileReconnecting = allowWhileReconnecting; exports.reachesNetworkWhileOffline = reachesNetworkWhileOffline; exports.canReachApi = canReachApi; exports.setOfflineState = setOfflineState; exports.OFFLINE_REPLAY_HEADER = OFFLINE_REPLAY_HEADER; exports.DEFAULT_SQLITE_MODULE_URL = DEFAULT_SQLITE_MODULE_URL; exports.DEVICE_WORKER_FILE = DEVICE_WORKER_FILE; exports.DEFAULT_DEVICE_WORKER_URL = DEFAULT_DEVICE_WORKER_URL; exports.OFFLINE_SQLITE_FILES = OFFLINE_SQLITE_FILES; exports.NeedsConnectionError = NeedsConnectionError; exports.patternToString = patternToString; exports.DeviceStoreUnavailableError = DeviceStoreUnavailableError; exports.OfflineUnavailableError = OfflineUnavailableError; exports.markOfflineUnavailable = markOfflineUnavailable; exports.isOfflineAvailable = isOfflineAvailable; exports.blockOfflineStore = blockOfflineStore; exports.unblockOfflineStore = unblockOfflineStore; exports.isOfflineStoreBlocked = isOfflineStoreBlocked; exports.configureOffline = configureOffline; exports.isOfflineConfigured = isOfflineConfigured; exports.isOfflineEnabledOnDevice = isOfflineEnabledOnDevice; exports.setOfflineEnabledOnDevice = setOfflineEnabledOnDevice; exports.writeOfflineLastSync = writeOfflineLastSync; exports.refreshOfflineDeviceState = refreshOfflineDeviceState; exports.rootKinds = rootKinds; exports.getOfflineConfig = getOfflineConfig; exports.setDefaultDeviceStoreOpener = setDefaultDeviceStoreOpener; exports.getSqliteModuleUrl = getSqliteModuleUrl; exports.getDeviceWorkerUrl = getDeviceWorkerUrl; exports.setDeviceStoreOpener = setDeviceStoreOpener; exports.getOfflineStore = getOfflineStore; exports.forgetOfflineStore = forgetOfflineStore;
|
|
322
|
+
//# sourceMappingURL=chunk-WUNSG3IN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-WUNSG3IN.js","../src/offline/state.ts","../src/offline/types.ts","../src/offline/config.ts"],"names":[],"mappings":"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","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/chunk-WUNSG3IN.js","sourcesContent":[null,"// Kept free of React: `directFetch` (every entry, server ones included) imports this module.\n// The hooks live in state-hooks.ts, exported only from the `./offline` entry.\n\nexport type OfflineState = {\n online: boolean;\n pending: number;\n conflicts: number;\n draining: boolean;\n lockedRootIds: string[];\n /**\n * False once this browser was found unable to keep the device copy (no secure context, no\n * private file storage, or the worker reports the OPFS APIs missing). Offline mode is then off\n * for the rest of the page: `isOfflineConfigured()` answers false and nothing offline runs.\n */\n available: boolean;\n /**\n * Offline mode is on on this device for the signed-in user. Always true once configured\n * without `OfflineConfig.requireOptIn`; otherwise the GM's per-device switch.\n */\n enabled: boolean;\n /** The running full sync: root records done out of the total, null when no sync runs. */\n syncProgress: { done: number; total: number } | null;\n /** When the last full sync on this device finished (epoch ms), null when never. */\n lastSyncedAt: number | null;\n /** How many root records the last full sync kept on this device, null when unknown. */\n rootCount: number | null;\n};\n\nexport const SERVER_SNAPSHOT: OfflineState = {\n online: true,\n pending: 0,\n conflicts: 0,\n draining: false,\n lockedRootIds: [],\n available: true,\n enabled: false,\n syncProgress: null,\n lastSyncedAt: null,\n rootCount: null,\n};\n\nlet _state: OfflineState = { ...SERVER_SNAPSHOT };\nconst _listeners = new Set<(s: OfflineState) => void>();\nlet _detachBrowserEvents: (() => void) | null = null;\n\nexport function getOfflineState(): OfflineState {\n return _state;\n}\n\nexport function subscribeOfflineState(listener: (s: OfflineState) => void): () => void {\n _listeners.add(listener);\n return () => {\n _listeners.delete(listener);\n };\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((value, index) => value === b[index]);\n }\n return a === b;\n}\n\n// A reconnect attempt: a probe reached the API while the session is offline. The session stays\n// offline (spec § 4: offline \"until a sync succeeds\") while the drain and the sync run; their\n// reads and the change-set request go to the network meanwhile (`reachesNetworkWhileOffline`).\n// Any network failure (`online: false` set again) ends the attempt.\nlet _reconnecting = false;\nconst _passThroughUrls = new Set<string>();\n\n/** Whether a reconnect attempt (drain then sync, after a probe reached the API) is running. */\nexport function isReconnecting(): boolean {\n return _reconnecting;\n}\n\n/** Starts or ends a reconnect attempt (the offline runtime). */\nexport function setReconnecting(value: boolean): void {\n _reconnecting = value;\n if (!value) _passThroughUrls.clear();\n}\n\n/** Lets one write (the drain's change-set request) reach the network during a reconnect attempt. */\nexport function allowWhileReconnecting(url: string): () => void {\n _passThroughUrls.add(url);\n return () => {\n _passThroughUrls.delete(url);\n };\n}\n\n/**\n * While the session is offline, whether a request still goes to the network: only during a\n * reconnect attempt, for a GET or a write the attempt let through. Any other write stays local\n * (queued), so it is sent after the waiting changes, in order.\n */\nexport function reachesNetworkWhileOffline(method: string, url: string): boolean {\n if (!_reconnecting) return false;\n return method.toUpperCase() === \"GET\" || _passThroughUrls.has(url);\n}\n\n/** The sync and the drain may talk to the API: online, or during a reconnect attempt. */\nexport function canReachApi(): boolean {\n return _state.online || _reconnecting;\n}\n\n/** Applies a partial change. Listeners run once, and only when a value actually changed. */\nexport function setOfflineState(patch: Partial<OfflineState>): void {\n if (patch.online === false) setReconnecting(false);\n const changed = (Object.keys(patch) as (keyof OfflineState)[]).some(\n (key) => patch[key] !== undefined && !sameValue(patch[key], _state[key]),\n );\n if (!changed) return;\n\n _state = { ..._state, ...patch };\n for (const listener of [..._listeners]) listener(_state);\n}\n\n/**\n * Follows the browser's offline event. Called by `configureOffline`, never at import, so an app\n * that does not opt in gets no listener. The browser's online event alone never brings the\n * session back online (spec § 4: offline \"until a sync succeeds\"): the runtime probes the API on\n * that event and goes online only when the probe reaches it.\n */\nexport function attachBrowserOnlineEvents(): void {\n if (_detachBrowserEvents || typeof window === \"undefined\") return;\n\n if (typeof navigator !== \"undefined\" && typeof navigator.onLine === \"boolean\") {\n setOfflineState({ online: navigator.onLine });\n }\n\n const onOffline = () => setOfflineState({ online: false });\n window.addEventListener(\"offline\", onOffline);\n _detachBrowserEvents = () => {\n window.removeEventListener(\"offline\", onOffline);\n };\n}\n\n/** Test helper: back to the initial state, browser events detached, listeners kept. */\nexport function resetOfflineState(): void {\n _detachBrowserEvents?.();\n _detachBrowserEvents = null;\n setReconnecting(false);\n _state = { ...SERVER_SNAPSHOT };\n}\n","import type { ApiRequestDataTypeInterface } from \"../core/interfaces/ApiRequestDataTypeInterface\";\nimport type { DeviceStore, StoredRecord } from \"./store/DeviceStore\";\n\n/** Header of a request the server runs as an offline replay. Never answered locally. */\nexport const OFFLINE_REPLAY_HEADER = \"x-offline-replay\";\n\nexport type OfflineMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\n/** A Module (matched by its endpoint), a \":param\" capture, or a literal segment (\"playing\", \"merge\"). */\nexport type PatternSegment = ApiRequestDataTypeInterface | string;\n\n/** `url` (beyond the contract, optional): the absolute URL the request was made to, for the `links` of a list. */\nexport type OfflineRequest = { method: OfflineMethod; path: string; query: URLSearchParams; body?: any; url?: string };\n\n/** `body` is a JSON:API document, `undefined` for a 204. */\nexport type OfflineAnswer = { status: number; body: any };\n\nexport type LocalAnswerContext = { request: OfflineRequest; params: Record<string, string>; store: DeviceStore };\n\nexport type LocalAnswer = (ctx: LocalAnswerContext) => Promise<OfflineAnswer>;\n\nexport type OfflineRoute = { method: OfflineMethod; pattern: PatternSegment[]; answer: LocalAnswer; queue: boolean };\n\n/**\n * A type the API reads only as a list per target record: each changed record's target is the\n * other end of its sync link of `linkKind` (from the record to the target), and `endpoint`\n * builds that target's list path with `EndpointCreator`.\n */\nexport type OfflineLinkedListFetch = {\n linkKind: string;\n endpoint: (rootId: string, target: { type: string; id: string }) => string;\n};\n\n/** One more kind of root record beside `rootModule` (e.g. a notebook). Optional. */\nexport type OfflineRootKind = {\n /** The module of the root records of this kind. Sync reads `{module}/:rootId/sync`. */\n module: ApiRequestDataTypeInterface;\n /** The ids of the roots of this kind to keep on the device. Throw to keep the device copy unchanged. */\n listSyncRoots: () => Promise<string[]>;\n /**\n * Per record type, the full list endpoint (query string included) that downloads every record of\n * that type under one root of this kind, built from the stored root record. Replaces the type's\n * `fetch` mode under this kind only. Never given `updatedSince`.\n */\n typeEndpoints?: {\n module: ApiRequestDataTypeInterface;\n endpoint: (root: { id: string; resource: StoredRecord[\"resource\"] }) => string;\n }[];\n /** The module whose model reads this kind's sync answer. Default: the library's `RootSync` module (`root-syncs`). */\n syncModule?: ApiRequestDataTypeInterface;\n};\n\ntype LocalWriteBase = { store: DeviceStore; module: ApiRequestDataTypeInterface; id: string }; // store = the write's transaction\n\n/** What a generic local write (`afterLocalWrite`) did, inside its transaction. */\nexport type OfflineLocalWriteContext =\n | (LocalWriteBase & { method: \"POST\"; resource: StoredRecord[\"resource\"]; previous: null })\n | (LocalWriteBase & {\n method: \"PUT\" | \"PATCH\";\n resource: StoredRecord[\"resource\"];\n previous: StoredRecord[\"resource\"];\n })\n | (LocalWriteBase & { method: \"DELETE\"; resource: null; previous: StoredRecord[\"resource\"] });\n\nexport type OfflineTypeConfig = {\n module: ApiRequestDataTypeInterface;\n /**\n * How the sync fetches the type's changed records: the root record's list (`root-list`), one\n * GET per record (`by-id`), or (`linked-list`) the list of each record's target, found through\n * the sync answer's links of `linkedList.linkKind` (e.g. player notes, read per target only).\n */\n fetch: \"root-list\" | \"by-id\" | \"linked-list\";\n /** Required with `fetch: \"linked-list\"`. */\n linkedList?: OfflineLinkedListFetch;\n readOnly: boolean;\n serverOwnedFields: string[];\n /**\n * Relationship name → Neo4j relationship type (`faction` → `MEMBER_OF`). A link the device\n * writes from a request's relationships carries the mapped type, the kind synced links carry;\n * an unmapped name is stored as the name itself.\n */\n relationshipKinds?: Record<string, string>;\n /** The string attributes the server's fulltext index covers (default: every string attribute). */\n searchFields?: string[];\n /** The server's order with no `orderBy` (default `updatedAt DESC`). */\n defaultOrderBy?: string;\n /**\n * Called by the generic POST/PUT/PATCH/DELETE local answers inside the same transaction as the\n * write and the enqueue (a throw rolls both back). Never called by sync or write-through.\n */\n afterLocalWrite?: (ctx: OfflineLocalWriteContext) => Promise<void>;\n};\n\nexport type OfflineConfig = {\n getUserId: () => string | undefined;\n /**\n * Offline mode is off on each device until the user turns it on (`turnOnOffline`), stored per\n * user per device. Default (undefined/false): always on, every device keeps the copy.\n */\n requireOptIn?: boolean;\n /** The module whose records own every other record (in Wyrdli, Modules.Campaign). */\n rootModule: ApiRequestDataTypeInterface;\n types: OfflineTypeConfig[];\n routes: OfflineRoute[];\n /** Ids of the root records to keep on the device. */\n listSyncRoots: () => Promise<string[]>;\n /** More kinds of root records beside `rootModule`, each synced and kept on its own (optional). */\n extraRootKinds?: OfflineRootKind[];\n shellPath: (locale: string) => string;\n syncIntervalMs: number;\n /**\n * Where the device worker loads SQLite from at run time (default `/offline-sqlite/index.mjs`).\n * SQLite is never bundled: its own helper worker uses a computed URL that app bundlers refuse.\n * The app serves the files of `dist/offline/sqlite/` at this URL's folder.\n */\n sqliteModuleUrl?: string;\n /**\n * Where the device-copy worker is started from (default `/offline-sqlite/device-worker.mjs`).\n * It is a standalone file in `dist/offline/sqlite/`, never bundled by the app.\n */\n deviceWorkerUrl?: string;\n};\n\nexport const DEFAULT_SQLITE_MODULE_URL = \"/offline-sqlite/index.mjs\";\nexport const DEVICE_WORKER_FILE = \"device-worker.mjs\";\nexport const DEFAULT_DEVICE_WORKER_URL = `/offline-sqlite/${DEVICE_WORKER_FILE}`;\n\n/**\n * The files of `dist/offline/sqlite/` the app serves: the device worker and the SQLite files\n * copied from @sqlite.org/sqlite-wasm.\n */\nexport const OFFLINE_SQLITE_FILES = [\n DEVICE_WORKER_FILE,\n \"index.mjs\",\n \"sqlite3.wasm\",\n \"sqlite3-opfs-async-proxy.js\",\n] as const;\n\n/** Thrown by a local answer for something that only the server can do. Answered as a 503 \"needs-connection\". */\nexport class NeedsConnectionError extends Error {\n readonly status = 503;\n readonly code = \"needs-connection\";\n\n constructor(message: string = \"Needs a connection\") {\n super(message);\n this.name = \"NeedsConnectionError\";\n }\n}\n\n/** Segments joined with \"/\", modules by their endpoint. */\nexport function patternToString(pattern: PatternSegment[]): string {\n return pattern.map((segment) => (typeof segment === \"string\" ? segment : segment.name)).join(\"/\");\n}\n","import { attachBrowserOnlineEvents, getOfflineState, setOfflineState } from \"./state\";\nimport type { DeviceStore } from \"./store/DeviceStore\";\nimport {\n DEFAULT_DEVICE_WORKER_URL,\n DEFAULT_SQLITE_MODULE_URL,\n NeedsConnectionError,\n type OfflineConfig,\n type OfflineRootKind,\n} from \"./types\";\n\n// Kept free of store, worker and React imports: `directFetch` reads `isOfflineConfigured()` on\n// every request, so this module is the only offline code an app that never opts in loads.\n\nlet _config: OfflineConfig | null = null;\nlet _opener: ((userId: string) => Promise<DeviceStore>) | null = null;\n// Registered by the `./offline` entry (configure.ts), so the store code is reachable only from it.\nlet _defaultOpener: ((userId: string) => Promise<DeviceStore>) | null = null;\nconst _stores = new Map<string, Promise<DeviceStore>>();\n// Users whose device store must not be opened again (logged out) until they sign in again.\nconst _blockedUsers = new Set<string>();\n// Per user: whether offline mode is on on this device (`requireOptIn`). Read from localStorage\n// once, since `isOfflineConfigured()` runs on every request.\nconst _enabledCache = new Map<string, boolean>();\n\nconst ENABLED_KEY_PREFIX = \"nja-offline-enabled:\";\nconst LAST_SYNC_KEY_PREFIX = \"nja-offline-last-sync:\";\n\nfunction readStorage(key: string): string | null {\n try {\n return typeof localStorage === \"undefined\" ? null : localStorage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction writeStorage(key: string, value: string | null): void {\n try {\n if (typeof localStorage === \"undefined\") return;\n if (value === null) localStorage.removeItem(key);\n else localStorage.setItem(key, value);\n } catch {\n // Storage can be blocked or full: the switch then lasts for this page only.\n }\n}\n\n/**\n * The signed-in user's device store cannot be used: it could not be opened (opfs-sahpool holds\n * one connection per origin, so a second tab cannot open it) or the user logged out. A request\n * answered from the device copy then needs a connection (503 \"needs-connection\").\n */\nexport class DeviceStoreUnavailableError extends NeedsConnectionError {\n constructor(message: string = \"The device copy is not available in this tab\") {\n super(message);\n this.name = \"DeviceStoreUnavailableError\";\n }\n}\n\n/**\n * This browser cannot keep the device copy at all: not a secure context (https or `localhost`),\n * no private file storage (`navigator.storage.getDirectory`), or the worker reports the OPFS\n * APIs missing. Offline mode switches off for the page (`markOfflineUnavailable`). A failure on\n * a browser that can keep the copy (the file held by another tab) is a `DeviceStoreUnavailableError`.\n */\nexport class OfflineUnavailableError extends DeviceStoreUnavailableError {\n constructor(reason: string) {\n super(`Offline mode isn't available in this browser: ${reason}`);\n this.name = \"OfflineUnavailableError\";\n }\n}\n\n/**\n * Switches offline mode off for this page, once: one console warning, `available: false` in the\n * offline state. From then on `isOfflineConfigured()` answers false, so no request, sync, drain,\n * write-through or lock check touches the device copy again.\n */\nexport function markOfflineUnavailable(error: OfflineUnavailableError): void {\n if (!getOfflineState().available) return;\n console.warn(`[offline] ${error.message}. Offline mode is off in this browser.`);\n setOfflineState({ available: false });\n}\n\n/** Whether this browser can keep the device copy (true until found otherwise). */\nexport function isOfflineAvailable(): boolean {\n return getOfflineState().available;\n}\n\n/** Logout: the user's store is never opened again in this page until `unblockOfflineStore`. */\nexport function blockOfflineStore(userId: string): void {\n _blockedUsers.add(userId);\n _stores.delete(userId);\n}\n\n/** A sign-in (`onUserSignedIn`): the user's store may be opened again. */\nexport function unblockOfflineStore(userId: string): void {\n _blockedUsers.delete(userId);\n}\n\nexport function isOfflineStoreBlocked(userId: string): boolean {\n return _blockedUsers.has(userId);\n}\n\n/** Opts the app into offline mode. Without this call nothing offline runs. */\nexport function configureOffline(config: OfflineConfig): void {\n _config = config;\n attachBrowserOnlineEvents();\n refreshOfflineDeviceState();\n}\n\n/**\n * Configured, the browser can keep the device copy (see `markOfflineUnavailable`), and offline\n * mode is on on this device for the signed-in user (see `requireOptIn`).\n */\nexport function isOfflineConfigured(): boolean {\n return _config !== null && isOfflineAvailable() && isOfflineEnabledOnDevice(_config.getUserId());\n}\n\n/**\n * Whether offline mode is on on this device for `userId`. Always true without\n * `OfflineConfig.requireOptIn`; otherwise the stored switch, false with no user.\n */\nexport function isOfflineEnabledOnDevice(userId?: string | null): boolean {\n if (!_config?.requireOptIn) return true;\n if (!userId) return false;\n let enabled = _enabledCache.get(userId);\n if (enabled === undefined) {\n enabled = readStorage(ENABLED_KEY_PREFIX + userId) === \"1\";\n _enabledCache.set(userId, enabled);\n }\n return enabled;\n}\n\n/** Stores the device switch for `userId` (`turnOnOffline` / `turnOffOffline`). */\nexport function setOfflineEnabledOnDevice(userId: string, enabled: boolean): void {\n writeStorage(ENABLED_KEY_PREFIX + userId, enabled ? \"1\" : null);\n _enabledCache.set(userId, enabled);\n}\n\n/** When `userId`'s last full sync on this device finished (epoch ms), or null. */\nexport function readOfflineLastSync(userId: string): number | null {\n const value = Number(readStorage(LAST_SYNC_KEY_PREFIX + userId));\n return Number.isFinite(value) && value > 0 ? value : null;\n}\n\n/** Stores, or with null removes, when `userId`'s last full sync finished. */\nexport function writeOfflineLastSync(userId: string, at: number | null): void {\n writeStorage(LAST_SYNC_KEY_PREFIX + userId, at === null ? null : String(at));\n}\n\n/**\n * Reads the device switch and the last sync time of the signed-in user into the offline state\n * (`enabled`, `lastSyncedAt`). Does nothing before `configureOffline`.\n */\nexport function refreshOfflineDeviceState(): void {\n if (!_config) return;\n const userId = _config.getUserId();\n if (userId) _enabledCache.delete(userId);\n setOfflineState({\n enabled: isOfflineEnabledOnDevice(userId),\n lastSyncedAt: userId ? readOfflineLastSync(userId) : null,\n });\n}\n\n/**\n * Every kind of root record: the primary one (`rootModule` + `listSyncRoots`) first, then\n * `extraRootKinds`. Library-internal (not exported from the entry).\n */\nexport function rootKinds(config: OfflineConfig): OfflineRootKind[] {\n return [{ module: config.rootModule, listSyncRoots: config.listSyncRoots }, ...(config.extraRootKinds ?? [])];\n}\n\nexport function getOfflineConfig(): OfflineConfig {\n if (!_config) throw new Error(\"Offline mode is not configured. Call configureOffline() first.\");\n return _config;\n}\n\n/** The browser opener, set by the `./offline` entry's `configureOffline`. */\nexport function setDefaultDeviceStoreOpener(opener: (userId: string) => Promise<DeviceStore>): void {\n _defaultOpener = opener;\n}\n\n/** The URL the device worker loads SQLite from (`OfflineConfig.sqliteModuleUrl`). */\nexport function getSqliteModuleUrl(): string {\n return _config?.sqliteModuleUrl ?? DEFAULT_SQLITE_MODULE_URL;\n}\n\n/** The URL the device worker is started from (`OfflineConfig.deviceWorkerUrl`). */\nexport function getDeviceWorkerUrl(): string {\n return _config?.deviceWorkerUrl ?? DEFAULT_DEVICE_WORKER_URL;\n}\n\n/** Replaces how a user's device store is opened (tests pass `openMemoryDeviceStore`). */\nexport function setDeviceStoreOpener(opener: ((userId: string) => Promise<DeviceStore>) | null): void {\n _opener = opener;\n _stores.clear();\n}\n\n/**\n * The signed-in user's device store, opened once per user id. Only the signed-in user's file is\n * ever opened; with no signed-in user the request needs a connection.\n */\nexport async function getOfflineStore(): Promise<DeviceStore> {\n const userId = getOfflineConfig().getUserId();\n if (!userId) throw new NeedsConnectionError(\"No signed-in user\");\n if (!isOfflineEnabledOnDevice(userId)) throw new DeviceStoreUnavailableError(\"Offline mode is off on this device\");\n if (_blockedUsers.has(userId)) throw new DeviceStoreUnavailableError(\"The device copy was deleted at logout\");\n if (!isOfflineAvailable()) throw new OfflineUnavailableError(\"it was found unable to keep the device copy\");\n\n let store = _stores.get(userId);\n if (!store) {\n const opener = _opener ?? _defaultOpener;\n if (!opener) throw new Error(\"No device store opener: configure offline mode through the ./offline entry.\");\n store = opener(userId).catch((error) => {\n if (error instanceof OfflineUnavailableError) markOfflineUnavailable(error);\n if (error instanceof NeedsConnectionError) throw error;\n console.warn(\"[offline] the device copy could not be opened\", error);\n throw new DeviceStoreUnavailableError(\n `The device copy could not be opened: ${String((error as Error)?.message ?? error)}`,\n );\n });\n _stores.set(userId, store);\n store.catch(() => _stores.delete(userId));\n }\n return store;\n}\n\n/** Forgets the opened store of a user (logout, deleted file). */\nexport function forgetOfflineStore(userId: string): void {\n _stores.delete(userId);\n}\n\n/** Test helper: back to \"not configured\". */\nexport function resetOfflineConfig(): void {\n _config = null;\n _opener = null;\n _stores.clear();\n _blockedUsers.clear();\n _enabledCache.clear();\n}\n"]}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
isReferralEnabled,
|
|
20
20
|
isRegistrationAllowed,
|
|
21
21
|
useWaitlistText
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-HAW5PNJG.mjs";
|
|
23
23
|
import {
|
|
24
24
|
getRoleId,
|
|
25
25
|
isRolesConfigured
|
|
@@ -96,10 +96,10 @@ import {
|
|
|
96
96
|
useIsMobile,
|
|
97
97
|
validateItalianTaxCode,
|
|
98
98
|
validatePartitaIva
|
|
99
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-RFKSJIQB.mjs";
|
|
100
100
|
import {
|
|
101
101
|
useOfflineState
|
|
102
|
-
} from "./chunk-
|
|
102
|
+
} from "./chunk-OY65RYD3.mjs";
|
|
103
103
|
import {
|
|
104
104
|
EndpointCreator,
|
|
105
105
|
ModuleRegistry,
|
|
@@ -110,16 +110,16 @@ import {
|
|
|
110
110
|
useI18nLocale,
|
|
111
111
|
useI18nRouter,
|
|
112
112
|
useI18nTranslations
|
|
113
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-UOTHRJD2.mjs";
|
|
114
114
|
import {
|
|
115
115
|
CURRENT_USER_STORAGE_KEY
|
|
116
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-AUD6ZLBB.mjs";
|
|
117
117
|
import {
|
|
118
118
|
isOfflineConfigured
|
|
119
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-4ZJIUTIV.mjs";
|
|
120
120
|
import {
|
|
121
121
|
ENV
|
|
122
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-MQ7TXALH.mjs";
|
|
123
123
|
import {
|
|
124
124
|
__name
|
|
125
125
|
} from "./chunk-PAWJFY3S.mjs";
|
|
@@ -10852,7 +10852,7 @@ import { useRef as useRef18 } from "react";
|
|
|
10852
10852
|
import dynamic from "next/dynamic";
|
|
10853
10853
|
import React18 from "react";
|
|
10854
10854
|
import { jsx as jsx91 } from "react/jsx-runtime";
|
|
10855
|
-
var BlockNoteEditor = dynamic(() => import("./BlockNoteEditor-
|
|
10855
|
+
var BlockNoteEditor = dynamic(() => import("./BlockNoteEditor-QIVV2OB4.mjs"), {
|
|
10856
10856
|
ssr: false
|
|
10857
10857
|
});
|
|
10858
10858
|
var BlockNoteEditorContainer = React18.memo(/* @__PURE__ */ __name(function EditorContainer(props) {
|
|
@@ -17081,7 +17081,7 @@ __name(BlockNoteEditorMentionSuggestionMenu, "BlockNoteEditorMentionSuggestionMe
|
|
|
17081
17081
|
import dynamic2 from "next/dynamic";
|
|
17082
17082
|
import React29 from "react";
|
|
17083
17083
|
import { jsx as jsx178 } from "react/jsx-runtime";
|
|
17084
|
-
var BlockNoteViewer = dynamic2(() => import("./BlockNoteViewer-
|
|
17084
|
+
var BlockNoteViewer = dynamic2(() => import("./BlockNoteViewer-HIUAJQRI.mjs").then((m) => m.BlockNoteViewer), { ssr: false });
|
|
17085
17085
|
var BlockNoteViewerContainer = React29.memo(/* @__PURE__ */ __name(function ViewerContainer(props) {
|
|
17086
17086
|
return /* @__PURE__ */ jsx178(BlockNoteViewer, { ...props });
|
|
17087
17087
|
}, "ViewerContainer"));
|
|
@@ -17363,7 +17363,7 @@ function useJsonApiGet(params) {
|
|
|
17363
17363
|
setLoading(true);
|
|
17364
17364
|
setError(null);
|
|
17365
17365
|
try {
|
|
17366
|
-
const { JsonApiGet } = await import("./JsonApiRequest-
|
|
17366
|
+
const { JsonApiGet } = await import("./JsonApiRequest-IKKHWCPB.mjs");
|
|
17367
17367
|
const language = navigator.language.split("-")[0] || "en";
|
|
17368
17368
|
const apiResponse = await JsonApiGet({
|
|
17369
17369
|
classKey: params.classKey,
|
|
@@ -17468,7 +17468,7 @@ function useJsonApiMutation(config) {
|
|
|
17468
17468
|
setLoading(true);
|
|
17469
17469
|
setError(null);
|
|
17470
17470
|
try {
|
|
17471
|
-
const { JsonApiPost, JsonApiPut, JsonApiPatch, JsonApiDelete } = await import("./JsonApiRequest-
|
|
17471
|
+
const { JsonApiPost, JsonApiPut, JsonApiPatch, JsonApiDelete } = await import("./JsonApiRequest-IKKHWCPB.mjs");
|
|
17472
17472
|
const language = navigator.language.split("-")[0] || "en";
|
|
17473
17473
|
let apiResponse;
|
|
17474
17474
|
switch (config.method) {
|
|
@@ -30784,4 +30784,4 @@ export {
|
|
|
30784
30784
|
useOAuthClients,
|
|
30785
30785
|
useOAuthClient
|
|
30786
30786
|
};
|
|
30787
|
-
//# sourceMappingURL=chunk-
|
|
30787
|
+
//# sourceMappingURL=chunk-YKNULEHB.mjs.map
|
|
@@ -4,7 +4,7 @@ var _chunkG4JR3SFVjs = require('./chunk-G4JR3SFV.js');
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkPMESKNKLjs = require('./chunk-PMESKNKL.js');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
var _chunk7QVYU63Ejs = require('./chunk-7QVYU63E.js');
|
|
@@ -40,7 +40,7 @@ var ServerSession = class {
|
|
|
40
40
|
const headerStore = await _headers.headers.call(void 0, );
|
|
41
41
|
const token = _optionalChain([cookieStore, 'access', _ => _.get, 'call', _2 => _2("token"), 'optionalAccess', _3 => _3.value]) || void 0;
|
|
42
42
|
const roles = _optionalChain([cookieStore, 'access', _4 => _4.get, 'call', _5 => _5("roles"), 'optionalAccess', _6 => _6.value]);
|
|
43
|
-
const viewportCookie = _optionalChain([cookieStore, 'access', _7 => _7.get, 'call', _8 => _8(
|
|
43
|
+
const viewportCookie = _optionalChain([cookieStore, 'access', _7 => _7.get, 'call', _8 => _8(_chunkPMESKNKLjs.VIEWPORT_COOKIE_NAME), 'optionalAccess', _9 => _9.value]);
|
|
44
44
|
return {
|
|
45
45
|
isLogged: !!token,
|
|
46
46
|
isAdministrator: !!roles && roles.includes(_chunkG4JR3SFVjs.getRoleId.call(void 0, ).Administrator),
|
|
@@ -88,7 +88,7 @@ var ServerSession = class {
|
|
|
88
88
|
if (!rawModules) return false;
|
|
89
89
|
const modules = JSON.parse(_pako.ungzip.call(void 0, Buffer.from(rawModules, "base64"), { toText: true }));
|
|
90
90
|
const selectedModule = modules.find((module) => module.id === params.module.moduleId);
|
|
91
|
-
return
|
|
91
|
+
return _chunkPMESKNKLjs.checkPermissionsFromServer.call(void 0, {
|
|
92
92
|
module: params.module,
|
|
93
93
|
action: params.action,
|
|
94
94
|
data: params.data,
|
|
@@ -138,4 +138,4 @@ _chunk7QVYU63Ejs.__name.call(void 0, readBuildId, "readBuildId");
|
|
|
138
138
|
|
|
139
139
|
|
|
140
140
|
exports.invalidateCacheTag = invalidateCacheTag; exports.invalidateCacheTags = invalidateCacheTags; exports.updateCacheTag = updateCacheTag; exports.ServerSession = ServerSession; exports.buildOfflineManifest = buildOfflineManifest;
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-ZYSNJKOP.js.map
|