@proappstore/sdk 1.16.95 → 1.16.97
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/README.md +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/offline/downloads.d.ts +44 -0
- package/dist/offline/downloads.d.ts.map +1 -0
- package/dist/offline/downloads.js +235 -0
- package/dist/offline/downloads.js.map +1 -0
- package/dist/offline/jobs.d.ts +78 -0
- package/dist/offline/jobs.d.ts.map +1 -0
- package/dist/offline/jobs.js +231 -0
- package/dist/offline/jobs.js.map +1 -0
- package/dist/offline/locks.d.ts +6 -0
- package/dist/offline/locks.d.ts.map +1 -0
- package/dist/offline/locks.js +47 -0
- package/dist/offline/locks.js.map +1 -0
- package/dist/offline/store.d.ts +94 -0
- package/dist/offline/store.d.ts.map +1 -0
- package/dist/offline/store.js +271 -0
- package/dist/offline/store.js.map +1 -0
- package/dist/offline.d.ts +8 -0
- package/dist/offline.d.ts.map +1 -0
- package/dist/offline.js +5 -0
- package/dist/offline.js.map +1 -0
- package/dist/sdk-version.js +1 -1
- package/dist/shell-resilience.d.ts +3 -1
- package/dist/shell-resilience.d.ts.map +1 -1
- package/dist/shell-resilience.js +2 -2
- package/dist/shell-resilience.js.map +1 -1
- package/dist/shell.d.ts +11 -2
- package/dist/shell.d.ts.map +1 -1
- package/dist/shell.js +49 -30
- package/dist/shell.js.map +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { OfflineError, offlineFailure } from './store.js';
|
|
2
|
+
import { offlineLock } from './locks.js';
|
|
3
|
+
const validId = (id) => {
|
|
4
|
+
if (!id || id.length > 256)
|
|
5
|
+
throw new OfflineError('invalid', 'Work ids must contain 1–256 characters.');
|
|
6
|
+
};
|
|
7
|
+
const snapshot = (value) => {
|
|
8
|
+
try {
|
|
9
|
+
return structuredClone(value);
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
throw offlineFailure(error);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const errorText = (error) => (error instanceof Error ? error.message : String(error)).slice(0, 1000);
|
|
16
|
+
const checkAbort = (signal) => { if (signal?.aborted)
|
|
17
|
+
throw new DOMException('Work cancelled.', 'AbortError'); };
|
|
18
|
+
export class LocalJobs {
|
|
19
|
+
store;
|
|
20
|
+
constructor(store) {
|
|
21
|
+
this.store = store;
|
|
22
|
+
}
|
|
23
|
+
create(input) {
|
|
24
|
+
input = snapshot({ id: input.id, kind: input.kind, input: input.input });
|
|
25
|
+
validId(input.id);
|
|
26
|
+
validId(input.kind);
|
|
27
|
+
return this.store.transaction(['jobs'], 'readwrite', (tx, done) => {
|
|
28
|
+
const request = tx.objectStore('jobs').get(input.id);
|
|
29
|
+
request.onsuccess = () => {
|
|
30
|
+
if (request.result) {
|
|
31
|
+
tx.abort();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const row = { ...input, checkpoint: null, result: null, status: 'pending', attempts: 0, updatedAt: Date.now(), error: null };
|
|
35
|
+
tx.objectStore('jobs').put(row, row.id);
|
|
36
|
+
done(row);
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
get(id) { return this.store.read('jobs', id); }
|
|
41
|
+
list(options = {}) { return this.store.page('jobs', options); }
|
|
42
|
+
update(id, change) {
|
|
43
|
+
return this.store.transaction(['jobs'], 'readwrite', (tx, done) => {
|
|
44
|
+
const request = tx.objectStore('jobs').get(id);
|
|
45
|
+
request.onsuccess = () => {
|
|
46
|
+
if (!request.result) {
|
|
47
|
+
tx.abort();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const next = { ...change(request.result), updatedAt: Date.now() };
|
|
51
|
+
tx.objectStore('jobs').put(next, id);
|
|
52
|
+
done(next);
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async checkpoint(id, value) { value = snapshot(value); await this.update(id, (row) => ({ ...row, checkpoint: value })); }
|
|
57
|
+
async setStatus(id, status) {
|
|
58
|
+
if (!['pending', 'running', 'paused', 'interrupted', 'completed', 'failed'].includes(status))
|
|
59
|
+
throw new OfflineError('invalid', 'Unknown local job status.');
|
|
60
|
+
await this.update(id, (row) => ({ ...row, status }));
|
|
61
|
+
}
|
|
62
|
+
/** No automatic execution. Re-entering run() passes the last committed checkpoint. */
|
|
63
|
+
async run(id, handler, options = {}) {
|
|
64
|
+
const signal = options.signal;
|
|
65
|
+
options = signal ? { signal } : {};
|
|
66
|
+
return this.store.runWork(() => offlineLock(`${this.store.databaseName}:jobs`, async () => {
|
|
67
|
+
checkAbort(options.signal);
|
|
68
|
+
const found = await this.get(id);
|
|
69
|
+
checkAbort(options.signal);
|
|
70
|
+
this.store.assertAccess();
|
|
71
|
+
if (!found)
|
|
72
|
+
throw new OfflineError('invalid', 'Local job does not exist.');
|
|
73
|
+
if (found.status === 'completed')
|
|
74
|
+
return found;
|
|
75
|
+
await this.update(id, (row) => ({ ...row, status: 'running', attempts: row.attempts + 1, error: null }));
|
|
76
|
+
let completed;
|
|
77
|
+
try {
|
|
78
|
+
checkAbort(options.signal);
|
|
79
|
+
this.store.assertAccess();
|
|
80
|
+
const result = snapshot(await handler(found.input, {
|
|
81
|
+
savedCheckpoint: found.checkpoint, signal: options.signal,
|
|
82
|
+
checkpoint: async (value) => { checkAbort(options.signal); await this.checkpoint(id, value); },
|
|
83
|
+
}));
|
|
84
|
+
checkAbort(options.signal);
|
|
85
|
+
this.store.assertAccess();
|
|
86
|
+
completed = await this.update(id, (row) => ({ ...row, result, status: 'completed' }));
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
// A locked account deliberately prevents further writes; its running job
|
|
90
|
+
// can be recovered after the owner explicitly opens it again.
|
|
91
|
+
try {
|
|
92
|
+
await this.update(id, (row) => ({ ...row, status: options.signal?.aborted ? 'paused' : 'failed', error: errorText(error) }));
|
|
93
|
+
}
|
|
94
|
+
catch { /* Preserve the original failure; no unlocked-account fallback. */ }
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
// A committed completion must not become retryable when access changes afterward.
|
|
98
|
+
checkAbort(options.signal);
|
|
99
|
+
this.store.assertAccess();
|
|
100
|
+
return completed;
|
|
101
|
+
}, true, options.signal ? { signal: options.signal } : {}), options.signal);
|
|
102
|
+
}
|
|
103
|
+
/** The same Web Lock excludes active SDK runners before recovery. */
|
|
104
|
+
async recover() {
|
|
105
|
+
return this.store.runWork(() => offlineLock(`${this.store.databaseName}:jobs`, () => this.store.transaction(['jobs'], 'readwrite', (tx, done) => {
|
|
106
|
+
let count = 0;
|
|
107
|
+
const request = tx.objectStore('jobs').openCursor();
|
|
108
|
+
request.onsuccess = () => {
|
|
109
|
+
const cursor = request.result;
|
|
110
|
+
if (!cursor) {
|
|
111
|
+
done(count);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const row = cursor.value;
|
|
115
|
+
if (row.status === 'running') {
|
|
116
|
+
cursor.update({ ...row, status: 'interrupted', updatedAt: Date.now() });
|
|
117
|
+
count++;
|
|
118
|
+
}
|
|
119
|
+
cursor.continue();
|
|
120
|
+
};
|
|
121
|
+
}), true));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** At-least-once delivery. Handlers MUST enforce server idempotency using operationId. */
|
|
125
|
+
export class SyncQueue {
|
|
126
|
+
store;
|
|
127
|
+
constructor(store) {
|
|
128
|
+
this.store = store;
|
|
129
|
+
}
|
|
130
|
+
async enqueue(input) {
|
|
131
|
+
input = snapshot({ id: input.id, kind: input.kind, payload: input.payload, idempotent: input.idempotent });
|
|
132
|
+
validId(input.id);
|
|
133
|
+
validId(input.kind);
|
|
134
|
+
if (input.idempotent !== true)
|
|
135
|
+
throw new OfflineError('invalid', 'Only explicitly idempotent operations may be queued.');
|
|
136
|
+
return this.store.transaction(['outbox'], 'readwrite', (tx, done) => {
|
|
137
|
+
const request = tx.objectStore('outbox').get(input.id);
|
|
138
|
+
request.onsuccess = () => {
|
|
139
|
+
// A duplicate id cannot replace another payload (including after delivery).
|
|
140
|
+
if (request.result) {
|
|
141
|
+
tx.abort();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const row = { id: input.id, kind: input.kind, payload: input.payload, status: 'pending', attempts: 0, updatedAt: Date.now(), error: null };
|
|
145
|
+
tx.objectStore('outbox').put(row, row.id);
|
|
146
|
+
done(row);
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
get(id) { return this.store.read('outbox', id); }
|
|
151
|
+
list(options = {}) { return this.store.page('outbox', options); }
|
|
152
|
+
async change(id, status, error, increment = false) {
|
|
153
|
+
return this.store.transaction(['outbox'], 'readwrite', (tx, done) => {
|
|
154
|
+
const request = tx.objectStore('outbox').get(id);
|
|
155
|
+
request.onsuccess = () => {
|
|
156
|
+
if (!request.result) {
|
|
157
|
+
tx.abort();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const row = request.result;
|
|
161
|
+
tx.objectStore('outbox').put({ ...row, status, error, attempts: row.attempts + Number(increment), updatedAt: Date.now() }, id);
|
|
162
|
+
done(undefined);
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
retry(id) {
|
|
167
|
+
return this.store.runWork(() => offlineLock(`${this.store.databaseName}:sync`, async () => {
|
|
168
|
+
const row = await this.get(id);
|
|
169
|
+
if (!row || row.status !== 'failed')
|
|
170
|
+
throw new OfflineError('invalid', 'Only a failed operation can be retried.');
|
|
171
|
+
await this.change(id, 'pending', null);
|
|
172
|
+
}, true));
|
|
173
|
+
}
|
|
174
|
+
/** Explicit caller action; never triggered automatically by an online event. */
|
|
175
|
+
flush(handlers, options = {}) {
|
|
176
|
+
const signal = options.signal;
|
|
177
|
+
const limit = options.limit ?? 50;
|
|
178
|
+
options = signal ? { signal } : {};
|
|
179
|
+
handlers = { ...handlers };
|
|
180
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 200)
|
|
181
|
+
throw new OfflineError('invalid', 'Flush limit must be between 1 and 200.');
|
|
182
|
+
return this.store.runWork(() => offlineLock(`${this.store.databaseName}:sync`, async () => {
|
|
183
|
+
checkAbort(options.signal);
|
|
184
|
+
const pending = await this.store.transaction(['outbox'], 'readonly', (tx, done) => {
|
|
185
|
+
const rows = [];
|
|
186
|
+
const request = tx.objectStore('outbox').openCursor();
|
|
187
|
+
request.onsuccess = () => {
|
|
188
|
+
const cursor = request.result;
|
|
189
|
+
if (!cursor || rows.length >= limit) {
|
|
190
|
+
done(rows);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const row = cursor.value;
|
|
194
|
+
// Running after acquiring the lock means a previous tab terminated.
|
|
195
|
+
if (row.status === 'pending' || row.status === 'running')
|
|
196
|
+
rows.push(row);
|
|
197
|
+
cursor.continue();
|
|
198
|
+
};
|
|
199
|
+
});
|
|
200
|
+
let completed = 0, failed = 0;
|
|
201
|
+
for (const row of pending) {
|
|
202
|
+
checkAbort(options.signal);
|
|
203
|
+
this.store.assertAccess();
|
|
204
|
+
const handler = Object.hasOwn(handlers, row.kind) ? handlers[row.kind] : undefined;
|
|
205
|
+
if (!handler) {
|
|
206
|
+
await this.change(row.id, 'failed', 'No handler registered for this operation.');
|
|
207
|
+
failed++;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
await this.change(row.id, 'running', null, true);
|
|
211
|
+
try {
|
|
212
|
+
checkAbort(options.signal);
|
|
213
|
+
this.store.assertAccess();
|
|
214
|
+
await handler(row.payload, { operationId: row.id, signal: options.signal });
|
|
215
|
+
await this.change(row.id, 'completed', null);
|
|
216
|
+
completed++;
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
await this.change(row.id, options.signal?.aborted ? 'pending' : 'failed', errorText(error));
|
|
220
|
+
if (options.signal?.aborted)
|
|
221
|
+
throw error;
|
|
222
|
+
failed++;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return { completed, failed };
|
|
226
|
+
}, true, options.signal ? { signal: options.signal } : {}), options.signal);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
export function createLocalJobs(store) { return new LocalJobs(store); }
|
|
230
|
+
export function createSyncQueue(store) { return new SyncQueue(store); }
|
|
231
|
+
//# sourceMappingURL=jobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/offline/jobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locks.d.ts","sourceRoot":"","sources":["../../src/offline/locks.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,kBAAkB,UAAQ,EAAE,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAuB/M"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { OfflineError } from './store.js';
|
|
2
|
+
// Web Locks coordinate tabs/workers. Non-browser tests use realm-local queues.
|
|
3
|
+
const queues = new Map();
|
|
4
|
+
const readers = new Map();
|
|
5
|
+
export async function offlineLock(name, work, requireBrowserLock = false, options = {}) {
|
|
6
|
+
if (typeof navigator !== 'undefined' && navigator.locks) {
|
|
7
|
+
return navigator.locks.request(`pas:${name}`, options, (lock) => {
|
|
8
|
+
if (!lock)
|
|
9
|
+
throw new OfflineError('busy', 'Local work is active. Cancel or finish it before clearing storage.');
|
|
10
|
+
return work();
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
if (requireBrowserLock && (typeof window !== 'undefined' || typeof self !== 'undefined'))
|
|
14
|
+
throw new OfflineError('unavailable', 'This browser cannot coordinate offline work between tabs.');
|
|
15
|
+
const run = () => { if (options.signal?.aborted)
|
|
16
|
+
throw new DOMException('Work cancelled.', 'AbortError'); return work(); };
|
|
17
|
+
if (options.ifAvailable && ((readers.get(name) ?? 0) > 0 || queues.has(name)))
|
|
18
|
+
throw new OfflineError('busy', 'Local work is active. Cancel or finish it before clearing storage.');
|
|
19
|
+
if (options.mode === 'shared') {
|
|
20
|
+
// Purge uses ifAvailable and never queues a writer ahead of nested readers.
|
|
21
|
+
const exclusive = queues.get(name);
|
|
22
|
+
if (exclusive)
|
|
23
|
+
await exclusive.catch(() => { });
|
|
24
|
+
readers.set(name, (readers.get(name) ?? 0) + 1);
|
|
25
|
+
try {
|
|
26
|
+
return await run();
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
const count = (readers.get(name) ?? 1) - 1;
|
|
30
|
+
if (count)
|
|
31
|
+
readers.set(name, count);
|
|
32
|
+
else
|
|
33
|
+
readers.delete(name);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const prior = queues.get(name) ?? Promise.resolve();
|
|
37
|
+
const next = prior.catch(() => { }).then(run);
|
|
38
|
+
queues.set(name, next);
|
|
39
|
+
try {
|
|
40
|
+
return await next;
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
if (queues.get(name) === next)
|
|
44
|
+
queues.delete(name);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=locks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locks.js","sourceRoot":"","sources":["../../src/offline/locks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,+EAA+E;AAC/E,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;AACnD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC1C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAI,IAAY,EAAE,IAAsB,EAAE,kBAAkB,GAAG,KAAK,EAAE,UAA0F,EAAE;IACjM,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QACxD,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC9D,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE,oEAAoE,CAAC,CAAC;YAChH,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,kBAAkB,IAAI,CAAC,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,IAAI,KAAK,WAAW,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,aAAa,EAAE,2DAA2D,CAAC,CAAC;IAC7L,MAAM,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;QAAE,MAAM,IAAI,YAAY,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3H,IAAI,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE,oEAAoE,CAAC,CAAC;IACpL,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,4EAA4E;QAC5E,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,SAAS;YAAE,MAAM,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC;YAAC,OAAO,MAAM,GAAG,EAAE,CAAC;QAAC,CAAC;gBACnB,CAAC;YAAC,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAAC,IAAI,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;;gBAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;IACzH,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IACpD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC;QAAC,OAAO,MAAM,IAAI,CAAC;IAAC,CAAC;YAClB,CAAC;QAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** Intentional local content, not a cache of authenticated API responses. */
|
|
2
|
+
export type OfflineScope = Readonly<{
|
|
3
|
+
kind: 'device';
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'account';
|
|
6
|
+
ownerId: string;
|
|
7
|
+
}>;
|
|
8
|
+
export type OfflineErrorCode = 'unavailable' | 'closed' | 'access-denied' | 'quota' | 'blocked' | 'invalid' | 'storage' | 'integrity' | 'network' | 'busy';
|
|
9
|
+
export declare class OfflineError extends Error {
|
|
10
|
+
readonly code: OfflineErrorCode;
|
|
11
|
+
constructor(code: OfflineErrorCode, message: string, options?: ErrorOptions);
|
|
12
|
+
}
|
|
13
|
+
export type OfflineStoreOptions = {
|
|
14
|
+
appId: string;
|
|
15
|
+
indexedDB?: IDBFactory;
|
|
16
|
+
} & ({
|
|
17
|
+
scope: {
|
|
18
|
+
kind: 'device';
|
|
19
|
+
};
|
|
20
|
+
canAccess?: () => boolean;
|
|
21
|
+
} | {
|
|
22
|
+
scope: {
|
|
23
|
+
kind: 'account';
|
|
24
|
+
ownerId: string;
|
|
25
|
+
};
|
|
26
|
+
canAccess: () => boolean;
|
|
27
|
+
});
|
|
28
|
+
export interface LocalRecord<T = unknown> {
|
|
29
|
+
id: string;
|
|
30
|
+
value: T;
|
|
31
|
+
updatedAt: number;
|
|
32
|
+
blobBytes: number;
|
|
33
|
+
blobType: string | null;
|
|
34
|
+
}
|
|
35
|
+
export interface LocalWrite<T = unknown> {
|
|
36
|
+
id: string;
|
|
37
|
+
value: T;
|
|
38
|
+
blob?: Blob;
|
|
39
|
+
}
|
|
40
|
+
export interface LocalPage {
|
|
41
|
+
after?: string;
|
|
42
|
+
limit?: number;
|
|
43
|
+
}
|
|
44
|
+
export type OfflineTable = 'records' | 'blobs' | 'downloads' | 'jobs' | 'outbox';
|
|
45
|
+
export declare const OFFLINE_SCHEMA_VERSION = 2;
|
|
46
|
+
export declare function offlineFailure(error: unknown): OfflineError;
|
|
47
|
+
/** Every handle stays bound to one app/owner. close() locks it; clear() deletes it. */
|
|
48
|
+
export declare class OfflineStore {
|
|
49
|
+
readonly scope: OfflineScope;
|
|
50
|
+
readonly appId: string;
|
|
51
|
+
readonly databaseName: string;
|
|
52
|
+
private readonly factory;
|
|
53
|
+
private readonly canAccess;
|
|
54
|
+
private closed;
|
|
55
|
+
private readonly active;
|
|
56
|
+
constructor(options: OfflineStoreOptions);
|
|
57
|
+
assertAccess(): void;
|
|
58
|
+
close(): void;
|
|
59
|
+
private open;
|
|
60
|
+
/** @internal Shared transaction primitive for the opt-in offline modules. */
|
|
61
|
+
transaction<T>(tables: OfflineTable[], mode: IDBTransactionMode, work: (tx: IDBTransaction, done: (value: T) => void) => void): Promise<T>;
|
|
62
|
+
/** @internal */
|
|
63
|
+
read<T>(table: OfflineTable, id: string): Promise<T | null>;
|
|
64
|
+
/** @internal */
|
|
65
|
+
write<T>(table: OfflineTable, id: string, value: T): Promise<void>;
|
|
66
|
+
/** @internal Bounded cursor listing; metadata stores contain no audio bytes. */
|
|
67
|
+
page<T>(table: OfflineTable, options?: LocalPage): Promise<T[]>;
|
|
68
|
+
put<T>(entry: LocalWrite<T>): Promise<LocalRecord<T>>;
|
|
69
|
+
get<T = unknown>(id: string): Promise<LocalRecord<T> | null>;
|
|
70
|
+
getBlob(id: string): Promise<Blob | null>;
|
|
71
|
+
list<T = unknown>(options?: LocalPage): Promise<LocalRecord<T>[]>;
|
|
72
|
+
delete(id: string): Promise<void>;
|
|
73
|
+
/** @internal Shared lease excludes purge until durable work finishes. */
|
|
74
|
+
runWork<T>(work: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
75
|
+
/** Rejects busy while SDK jobs/downloads/sync are active. Cancel and await runners before retrying. */
|
|
76
|
+
clear(): Promise<void>;
|
|
77
|
+
/** Portable JSON export of one user-selected record, including an optional base64 blob. */
|
|
78
|
+
exportRecord(id: string): Promise<Blob>;
|
|
79
|
+
}
|
|
80
|
+
export declare function createOfflineStore(options: OfflineStoreOptions): OfflineStore;
|
|
81
|
+
/** Call on explicit logout/account changes; closing never deletes unsynced work. */
|
|
82
|
+
export declare function bindOfflineAccount(store: OfflineStore, auth: {
|
|
83
|
+
onChange: (listener: (user: {
|
|
84
|
+
id: string;
|
|
85
|
+
} | null) => void) => () => void;
|
|
86
|
+
}): () => void;
|
|
87
|
+
/** Persistence is a request, never a promise that the browser cannot remove data. */
|
|
88
|
+
export declare function localStorageStatus(requestPersistence?: boolean): Promise<{
|
|
89
|
+
supported: boolean;
|
|
90
|
+
persisted: boolean;
|
|
91
|
+
usage: number | null;
|
|
92
|
+
quota: number | null;
|
|
93
|
+
}>;
|
|
94
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/offline/store.ts"],"names":[],"mappings":"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"}
|