bleam 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/ai.cjs +3984 -25
  2. package/dist/ai.d.cts +503 -20
  3. package/dist/ai.d.ts +503 -20
  4. package/dist/ai.js +3946 -26
  5. package/dist/animated.cjs +1 -1
  6. package/dist/animated.js +1 -1
  7. package/dist/app.cjs +92 -0
  8. package/dist/app.js +92 -0
  9. package/dist/cli.cjs +653 -86
  10. package/dist/cli.d.cts +89 -1
  11. package/dist/cli.d.ts +89 -1
  12. package/dist/cli.js +654 -88
  13. package/dist/{config-ClDGHNb3.d.ts → config-Cms0rvqg.d.ts} +1 -0
  14. package/dist/{config-D3gPaVMb.d.cts → config-CufOVJV3.d.cts} +1 -0
  15. package/dist/config.d.cts +1 -1
  16. package/dist/config.d.ts +1 -1
  17. package/dist/crypto.d.cts +0 -2
  18. package/dist/crypto.d.ts +1 -1
  19. package/dist/dev-protocol.d.cts +14 -1
  20. package/dist/dev-protocol.d.ts +14 -1
  21. package/dist/files-Bo7h9fik.cjs +468 -0
  22. package/dist/files-Ds1wT8C2.js +445 -0
  23. package/dist/files-DwA7pzr3.d.cts +99 -0
  24. package/dist/files-VrkQlKIT.d.ts +99 -0
  25. package/dist/files.cjs +7 -0
  26. package/dist/files.d.cts +2 -0
  27. package/dist/files.d.ts +2 -0
  28. package/dist/files.js +4 -0
  29. package/dist/index.d.cts +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/native-sqlite-xcGdamRD.js +64 -0
  32. package/dist/native-sqlite-yQLD5s9i.cjs +66 -0
  33. package/dist/platform.cjs +27 -0
  34. package/dist/platform.d.cts +39 -0
  35. package/dist/platform.d.ts +39 -0
  36. package/dist/platform.js +21 -0
  37. package/dist/runtime.d.cts +1 -6
  38. package/dist/runtime.d.ts +1 -6
  39. package/dist/{schema-ipsECAso.d.ts → schema-DOOjfXvs.d.ts} +1 -1
  40. package/dist/{schema-BOuUHcqo.d.cts → schema-ENSMX_1t.d.cts} +1 -1
  41. package/dist/schema.cjs +1 -1
  42. package/dist/schema.d.cts +1 -1
  43. package/dist/schema.d.ts +1 -1
  44. package/dist/schema.js +1 -1
  45. package/dist/state-Bx0VlTlO.cjs +852 -0
  46. package/dist/state-CAwe-Vw1.js +767 -0
  47. package/dist/state.cjs +17 -763
  48. package/dist/state.d.cts +107 -77
  49. package/dist/state.d.ts +107 -77
  50. package/dist/state.js +4 -745
  51. package/dist/ui-1WepaMS4.d.cts +92 -0
  52. package/dist/ui-Ce-pnUUA.d.ts +92 -0
  53. package/dist/ui.cjs +286 -35
  54. package/dist/ui.d.cts +2 -30
  55. package/dist/ui.d.ts +2 -30
  56. package/dist/ui.js +283 -36
  57. package/dist/window.cjs +596 -0
  58. package/dist/window.d.cts +63 -0
  59. package/dist/window.d.ts +63 -0
  60. package/dist/window.js +589 -0
  61. package/package.json +16 -14
  62. package/templates/basic/app/index.tsx +8 -5
  63. package/templates/foundation-models/app/index.tsx +32 -0
  64. package/templates/foundation-models/app.config.ts +5 -0
  65. package/templates/image-generation/app/index.tsx +39 -0
  66. package/templates/image-generation/app.config.ts +5 -0
  67. package/templates/state/app/index.tsx +30 -0
  68. package/templates/state/app.config.ts +5 -0
  69. package/dist/chrome.cjs +0 -265
  70. package/dist/chrome.d.cts +0 -19
  71. package/dist/chrome.d.ts +0 -19
  72. package/dist/chrome.js +0 -262
  73. package/dist/fs.cjs +0 -13
  74. package/dist/fs.d.cts +0 -8
  75. package/dist/fs.d.ts +0 -8
  76. package/dist/fs.js +0 -12
  77. package/dist/native-macos-D6p2SmUj.js +0 -20
  78. package/dist/native-macos-DLwo_ii9.cjs +0 -31
  79. package/dist/native-runtime-CbPzrs8j.d.cts +0 -33
  80. package/dist/native-runtime-DxHSrsTX.d.ts +0 -33
  81. package/dist/native.cjs +0 -135
  82. package/dist/native.d.cts +0 -34
  83. package/dist/native.d.ts +0 -34
  84. package/dist/native.js +0 -135
  85. /package/dist/{schema-DVmoD9JL.js → schema-Bo5Jvqus.js} +0 -0
  86. /package/dist/{schema-bxeeCyLn.cjs → schema-rQ13mrpD.cjs} +0 -0
package/dist/state.js CHANGED
@@ -1,747 +1,6 @@
1
1
  import "./native-runtime-C85Nuc4F.js";
2
- import { t as crypto } from "./crypto-BB92-Upx.js";
3
- import { n as schema } from "./schema-DVmoD9JL.js";
4
- import { useSyncExternalStore } from "react";
5
- import { openOrCreate } from "@nativescript-community/sqlite";
2
+ import "./crypto-BB92-Upx.js";
3
+ import { a as isLinked, c as useField, d as LiveStore, f as atom, i as collection, l as useList, m as useStore, n as useSetting, o as link, p as useAtom, r as Collection, s as unlink, t as setting, u as useView } from "./state-CAwe-Vw1.js";
4
+ import "./schema-Bo5Jvqus.js";
6
5
 
7
- //#region src/state/atom.ts
8
- var LiveStore = class {
9
- listeners = /* @__PURE__ */ new Set();
10
- constructor(value) {
11
- this.value = value;
12
- }
13
- get() {
14
- return this.value;
15
- }
16
- set(value) {
17
- if (Object.is(this.value, value)) return;
18
- this.value = value;
19
- for (const listener of this.listeners) listener();
20
- }
21
- update(updater) {
22
- this.set(updater(this.value));
23
- }
24
- subscribe(listener) {
25
- this.listeners.add(listener);
26
- return () => {
27
- this.listeners.delete(listener);
28
- };
29
- }
30
- };
31
- function atom(initialValue) {
32
- return new LiveStore(initialValue);
33
- }
34
- function useStore(store) {
35
- return useSyncExternalStore(store.subscribe.bind(store), store.get.bind(store), store.get.bind(store));
36
- }
37
- function useAtom(value) {
38
- return useStore(value);
39
- }
40
-
41
- //#endregion
42
- //#region src/native-sqlite.ts
43
- const databases = /* @__PURE__ */ new Map();
44
- function documentsDirectory() {
45
- const path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.Document, NSSearchPathDomainMask.UserDomain, true).objectAtIndex(0);
46
- if (!path) throw new Error("Could not resolve documents directory");
47
- return String(path);
48
- }
49
- function ensureDirectory(path) {
50
- const fileManager = NSFileManager.defaultManager;
51
- if (fileManager.fileExistsAtPath(path)) return;
52
- fileManager.createDirectoryAtPathWithIntermediateDirectoriesAttributesError(path, true, null, null);
53
- }
54
- function databasePath(name) {
55
- const directory = `${documentsDirectory()}/bleam`;
56
- ensureDirectory(directory);
57
- return `${directory}/${name}`;
58
- }
59
- function toPluginParameters(parameters) {
60
- return parameters;
61
- }
62
- function toSQLiteValue(value) {
63
- if (typeof value === "string" || typeof value === "number" || value === null) return value;
64
- throw new Error("SQLite blobs are not supported by Bleam state yet");
65
- }
66
- function toSQLiteRow(row) {
67
- const output = {};
68
- for (const [key, value] of Object.entries(row)) output[key] = toSQLiteValue(value);
69
- return output;
70
- }
71
- var NativeSQLiteDatabase = class {
72
- constructor(database$1) {
73
- this.database = database$1;
74
- }
75
- execute(query, parameters) {
76
- return this.database.execute(query, toPluginParameters(parameters));
77
- }
78
- async select(query, parameters) {
79
- return (await this.database.select(query, toPluginParameters(parameters))).map(toSQLiteRow);
80
- }
81
- async get(query, parameters) {
82
- const row = await this.database.get(query, toPluginParameters(parameters));
83
- return row ? toSQLiteRow(row) : void 0;
84
- }
85
- transaction(action) {
86
- return this.database.transaction(action);
87
- }
88
- close() {
89
- this.database.close();
90
- }
91
- };
92
- function openNativeSQLiteDatabase(name = "bleam.sqlite3") {
93
- const path = databasePath(name);
94
- const existing = databases.get(path);
95
- if (existing) return new NativeSQLiteDatabase(existing);
96
- const database$1 = openOrCreate(path);
97
- databases.set(path, database$1);
98
- return new NativeSQLiteDatabase(database$1);
99
- }
100
-
101
- //#endregion
102
- //#region src/state/collection.ts
103
- const database = openNativeSQLiteDatabase();
104
- const recordMetadata = /* @__PURE__ */ new WeakMap();
105
- const recordAttachments = /* @__PURE__ */ new WeakMap();
106
- const collectionsByName = /* @__PURE__ */ new Map();
107
- let schemaInitialized;
108
- async function initializeCollectionSchema() {
109
- schemaInitialized ??= (async () => {
110
- await database.execute("PRAGMA journal_mode = WAL");
111
- await database.execute(`CREATE TABLE IF NOT EXISTS collections (
112
- collection TEXT NOT NULL,
113
- id TEXT NOT NULL,
114
- data TEXT NOT NULL,
115
- createdAt TEXT NOT NULL,
116
- updatedAt TEXT NOT NULL,
117
- version INTEGER NOT NULL DEFAULT 1,
118
- PRIMARY KEY (collection, id)
119
- )`);
120
- await database.execute(`CREATE TABLE IF NOT EXISTS links (
121
- id TEXT PRIMARY KEY,
122
- collections TEXT NOT NULL,
123
- ids TEXT NOT NULL,
124
- createdAt TEXT NOT NULL
125
- )`);
126
- await database.execute(`CREATE TABLE IF NOT EXISTS pins (
127
- sourceCollection TEXT NOT NULL,
128
- sourceId TEXT NOT NULL,
129
- name TEXT NOT NULL,
130
- targetCollection TEXT NOT NULL,
131
- targetId TEXT NOT NULL,
132
- createdAt TEXT NOT NULL,
133
- updatedAt TEXT NOT NULL,
134
- PRIMARY KEY (sourceCollection, sourceId, name)
135
- )`);
136
- await database.execute("CREATE INDEX IF NOT EXISTS collections_collection_createdAt_idx ON collections(collection, createdAt)");
137
- await database.execute("CREATE UNIQUE INDEX IF NOT EXISTS links_collections_ids_idx ON links(collections, ids)");
138
- await database.execute("CREATE INDEX IF NOT EXISTS links_collections_idx ON links(collections)");
139
- await database.execute("CREATE INDEX IF NOT EXISTS pins_source_idx ON pins(sourceCollection, sourceId)");
140
- await database.execute("CREATE INDEX IF NOT EXISTS pins_target_idx ON pins(targetCollection, targetId)");
141
- })();
142
- return schemaInitialized;
143
- }
144
- function rowValue(row, key) {
145
- const value = row[key];
146
- if (typeof value !== "string") throw new Error(`Expected SQLite row field ${key} to be a string`);
147
- return value;
148
- }
149
- function parsePersistedRow(row) {
150
- return {
151
- id: rowValue(row, "id"),
152
- data: rowValue(row, "data")
153
- };
154
- }
155
- function isReservedRecordField(key) {
156
- return key === "id" || key === "data" || key === "delete" || key === "set" || key === "with";
157
- }
158
- function assertCollectionShape(name, shape) {
159
- for (const key of Object.keys(shape)) if (isReservedRecordField(key)) throw new Error(`Collection "${name}" field "${key}" is reserved by Bleam records`);
160
- }
161
- function attachmentKey(value) {
162
- return typeof value === "string" ? `pin:${value}` : `join:${value.name}`;
163
- }
164
- function setAttachment(record, key, value) {
165
- let attachments = recordAttachments.get(record);
166
- if (!attachments) {
167
- attachments = /* @__PURE__ */ new Map();
168
- recordAttachments.set(record, attachments);
169
- }
170
- attachments.set(key, value);
171
- }
172
- function getAttachment(record, key) {
173
- return recordAttachments.get(record)?.get(key);
174
- }
175
- function extractRecordData(collection$1, record) {
176
- const output = {};
177
- for (const key of Object.keys(collection$1.shape)) {
178
- if (isReservedRecordField(key)) throw new Error(`Collection "${collection$1.name}" field "${key}" is reserved by Bleam records`);
179
- const value = record[key];
180
- if (value !== void 0) output[key] = value;
181
- }
182
- return collection$1.validator.parse(output);
183
- }
184
- function applyRecordData(collection$1, record, data) {
185
- for (const key of Object.keys(collection$1.shape)) {
186
- if (key in data) {
187
- Object.defineProperty(record, key, {
188
- value: data[key],
189
- enumerable: true,
190
- writable: true,
191
- configurable: true
192
- });
193
- continue;
194
- }
195
- delete record[key];
196
- }
197
- }
198
- function createRecord(collection$1, id, data) {
199
- const record = {};
200
- Object.defineProperty(record, "id", {
201
- value: id,
202
- enumerable: true,
203
- writable: false,
204
- configurable: false
205
- });
206
- applyRecordData(collection$1, record, data);
207
- Object.defineProperty(record, "data", {
208
- value() {
209
- return recordMetadata.has(this) ? extractRecordData(collection$1, this) : void 0;
210
- },
211
- enumerable: true,
212
- writable: false,
213
- configurable: false
214
- });
215
- Object.defineProperty(record, "delete", {
216
- value() {
217
- return collection$1.delete(this);
218
- },
219
- enumerable: true,
220
- writable: false,
221
- configurable: false
222
- });
223
- Object.defineProperty(record, "set", {
224
- get() {
225
- return (patch) => collection$1.update(this, patch);
226
- },
227
- enumerable: true,
228
- configurable: false
229
- });
230
- Object.defineProperty(record, "with", {
231
- value(value) {
232
- return getAttachment(this, attachmentKey(value)) ?? (typeof value === "string" ? void 0 : []);
233
- },
234
- enumerable: true,
235
- writable: false,
236
- configurable: false
237
- });
238
- recordMetadata.set(record, {
239
- collection: collection$1,
240
- id
241
- });
242
- return record;
243
- }
244
- function decodeRecordData(collection$1, data) {
245
- const value = JSON.parse(data);
246
- return collection$1.validator.parse(value);
247
- }
248
- function encodeRecordData(collection$1, data) {
249
- return JSON.stringify(collection$1.validator.parse(data));
250
- }
251
- function metadataFor(record) {
252
- const metadata = recordMetadata.get(record);
253
- if (!metadata) throw new Error("Expected a collection record loaded by Bleam");
254
- return metadata;
255
- }
256
- function resolveRecordReference(first, second) {
257
- if (first instanceof Collection) {
258
- if (!second) throw new Error("Expected a record id");
259
- return {
260
- collection: first,
261
- id: second
262
- };
263
- }
264
- return metadataFor(first);
265
- }
266
- function encodePart(value) {
267
- return encodeURIComponent(value);
268
- }
269
- function encodePair(first, second) {
270
- return `${encodePart(first)}:${encodePart(second)}`;
271
- }
272
- function decodePair(value) {
273
- const parts = value.split(":");
274
- if (parts.length !== 2 || parts[0] === void 0 || parts[1] === void 0) throw new Error(`Invalid encoded link pair "${value}"`);
275
- return [decodeURIComponent(parts[0]), decodeURIComponent(parts[1])];
276
- }
277
- function storedLinkFor(first, second) {
278
- const sameCollection = first.collection.name === second.collection.name;
279
- const ordered = first.collection.name < second.collection.name || sameCollection && first.id <= second.id ? [first, second] : [second, first];
280
- const collections = encodePair(ordered[0].collection.name, ordered[1].collection.name);
281
- const ids = encodePair(ordered[0].id, ordered[1].id);
282
- return {
283
- id: encodePair(collections, ids),
284
- collections,
285
- ids
286
- };
287
- }
288
- function linkIncludesRecord(row, collectionName, id) {
289
- const [firstCollection, secondCollection] = decodePair(rowValue(row, "collections"));
290
- const [firstId, secondId] = decodePair(rowValue(row, "ids"));
291
- return firstCollection === collectionName && firstId === id || secondCollection === collectionName && secondId === id;
292
- }
293
- function linkedIdFromRow(row, source, targetName) {
294
- const [firstCollection, secondCollection] = decodePair(rowValue(row, "collections"));
295
- const [firstId, secondId] = decodePair(rowValue(row, "ids"));
296
- if (firstCollection === source.collection.name && firstId === source.id && secondCollection === targetName) return secondId;
297
- if (secondCollection === source.collection.name && secondId === source.id && firstCollection === targetName) return firstId;
298
- }
299
- function collectionForName(name) {
300
- const collection$1 = collectionsByName.get(name);
301
- if (!collection$1) throw new Error(`Unknown collection "${name}"`);
302
- return collection$1;
303
- }
304
- async function notifyCollections(...names) {
305
- for (const name of new Set(names)) await collectionForName(name).refreshQueries();
306
- }
307
- var Collection = class {
308
- validator;
309
- queries = /* @__PURE__ */ new Set();
310
- store = {
311
- loaded: false,
312
- records: /* @__PURE__ */ new Map(),
313
- order: [],
314
- listListeners: /* @__PURE__ */ new Set(),
315
- recordListeners: /* @__PURE__ */ new Map()
316
- };
317
- constructor(name, shape) {
318
- this.name = name;
319
- this.shape = shape;
320
- assertCollectionShape(name, shape);
321
- if (collectionsByName.has(name)) throw new Error(`Collection "${name}" is already registered`);
322
- collectionsByName.set(name, this);
323
- this.validator = schema(shape);
324
- }
325
- initialize() {
326
- return initializeCollectionSchema();
327
- }
328
- async load() {
329
- if (this.store.loaded) return;
330
- this.store.loading ??= (async () => {
331
- await this.initialize();
332
- const rows = await database.select("SELECT id, data FROM collections WHERE collection = ? ORDER BY createdAt ASC", [this.name]);
333
- this.store.records.clear();
334
- this.store.order = [];
335
- for (const row of rows) {
336
- const persisted = parsePersistedRow(row);
337
- const data = decodeRecordData(this, persisted.data);
338
- const record = createRecord(this, persisted.id, data);
339
- this.store.records.set(persisted.id, record);
340
- this.store.order.push(persisted.id);
341
- }
342
- this.store.loaded = true;
343
- })();
344
- return this.store.loading;
345
- }
346
- notifyRecordListeners(id) {
347
- const listeners = this.store.recordListeners.get(id);
348
- if (!listeners) return;
349
- for (const listener of listeners) listener();
350
- }
351
- currentRecords() {
352
- const records = [];
353
- for (const id of this.store.order) {
354
- const record = this.store.records.get(id);
355
- if (record) records.push(record);
356
- }
357
- return records;
358
- }
359
- async refreshQueries() {
360
- for (const query of this.queries) await query.refresh();
361
- for (const listener of this.store.listListeners) listener();
362
- }
363
- async insert(value) {
364
- await this.load();
365
- const parsed = this.validator.parse(value);
366
- const id = crypto.randomUUID();
367
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
368
- const parameters = [
369
- this.name,
370
- id,
371
- encodeRecordData(this, parsed),
372
- timestamp,
373
- timestamp
374
- ];
375
- await database.execute(`INSERT INTO collections (collection, id, data, createdAt, updatedAt, version)
376
- VALUES (?, ?, ?, ?, ?, 1)`, parameters);
377
- const record = createRecord(this, id, parsed);
378
- this.store.records.set(id, record);
379
- this.store.order.push(id);
380
- await this.refreshQueries();
381
- this.notifyRecordListeners(id);
382
- return record;
383
- }
384
- async update(record, value) {
385
- await this.load();
386
- const id = typeof record === "string" ? record : metadataFor(record).id;
387
- const loadedRecord = this.store.records.get(id);
388
- if (!loadedRecord) throw new Error("Cannot update a collection record that was not loaded by Bleam");
389
- if (Object.keys(value).filter((key) => key in this.shape).length === 0) return;
390
- const next = this.validator.parse({
391
- ...extractRecordData(this, loadedRecord),
392
- ...value
393
- });
394
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
395
- await database.execute(`UPDATE collections
396
- SET data = ?, updatedAt = ?, version = version + 1
397
- WHERE collection = ? AND id = ?`, [
398
- encodeRecordData(this, next),
399
- timestamp,
400
- this.name,
401
- id
402
- ]);
403
- applyRecordData(this, loadedRecord, next);
404
- this.notifyRecordListeners(id);
405
- }
406
- async delete(record) {
407
- await this.load();
408
- const id = typeof record === "string" ? record : metadataFor(record).id;
409
- const loadedRecord = this.store.records.get(id);
410
- if (!loadedRecord) throw new Error("Cannot delete a collection record that was not loaded by Bleam");
411
- const affectedCollections = new Set([this.name]);
412
- await database.transaction(async () => {
413
- await database.execute("DELETE FROM collections WHERE collection = ? AND id = ?", [this.name, id]);
414
- for (const collectionName of await this.deleteLinksForRecord(id)) affectedCollections.add(collectionName);
415
- for (const collectionName of await this.deletePinsForRecord(id)) affectedCollections.add(collectionName);
416
- });
417
- this.store.records.delete(id);
418
- this.store.order = this.store.order.filter((currentId) => currentId !== id);
419
- recordMetadata.delete(loadedRecord);
420
- this.notifyRecordListeners(id);
421
- await notifyCollections(...affectedCollections);
422
- }
423
- async all() {
424
- await this.load();
425
- return this.currentRecords();
426
- }
427
- async get(id) {
428
- await this.load();
429
- return this.store.records.get(id);
430
- }
431
- async pin(record, name, target, targetId) {
432
- const sourceId = typeof record === "string" ? record : metadataFor(record).id;
433
- const targetReference = resolveRecordReference(target, targetId);
434
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
435
- await initializeCollectionSchema();
436
- await database.execute(`INSERT INTO pins (sourceCollection, sourceId, name, targetCollection, targetId, createdAt, updatedAt)
437
- VALUES (?, ?, ?, ?, ?, ?, ?)
438
- ON CONFLICT(sourceCollection, sourceId, name)
439
- DO UPDATE SET
440
- targetCollection = excluded.targetCollection,
441
- targetId = excluded.targetId,
442
- updatedAt = excluded.updatedAt`, [
443
- this.name,
444
- sourceId,
445
- name,
446
- targetReference.collection.name,
447
- targetReference.id,
448
- timestamp,
449
- timestamp
450
- ]);
451
- await this.refreshQueries();
452
- }
453
- async unpin(record, name) {
454
- const sourceId = typeof record === "string" ? record : metadataFor(record).id;
455
- await initializeCollectionSchema();
456
- await database.execute("DELETE FROM pins WHERE sourceCollection = ? AND sourceId = ? AND name = ?", [
457
- this.name,
458
- sourceId,
459
- name
460
- ]);
461
- await this.refreshQueries();
462
- }
463
- subscribeRecord(record, listener) {
464
- const id = metadataFor(record).id;
465
- let listeners = this.store.recordListeners.get(id);
466
- if (!listeners) {
467
- listeners = /* @__PURE__ */ new Set();
468
- this.store.recordListeners.set(id, listeners);
469
- }
470
- listeners.add(listener);
471
- return () => {
472
- listeners.delete(listener);
473
- if (listeners.size === 0) this.store.recordListeners.delete(id);
474
- };
475
- }
476
- queryStore(query) {
477
- const subscription = {
478
- value: [],
479
- listeners: /* @__PURE__ */ new Set(),
480
- refresh: async () => {
481
- subscription.value = await this.executeQuery(query);
482
- for (const listener of subscription.listeners) listener();
483
- }
484
- };
485
- this.queries.add(subscription);
486
- subscription.refresh();
487
- return {
488
- get() {
489
- return subscription.value;
490
- },
491
- subscribe: (listener) => {
492
- subscription.listeners.add(listener);
493
- return () => {
494
- subscription.listeners.delete(listener);
495
- if (subscription.listeners.size === 0) this.queries.delete(subscription);
496
- };
497
- }
498
- };
499
- }
500
- async executeQuery(query) {
501
- await this.load();
502
- let records = this.currentRecords();
503
- for (const join of query?.joins ?? []) {
504
- const target = join.kind === "record" ? metadataFor(join.record) : {
505
- collection: join.collection,
506
- id: join.id
507
- };
508
- const filtered = [];
509
- for (const record of records) if (await areLinked(metadataFor(record), target)) filtered.push(record);
510
- records = filtered;
511
- }
512
- for (const include of query?.joinIncludes ?? []) for (const record of records) {
513
- const linked = await linkedRecords(metadataFor(record), include.collection);
514
- setAttachment(record, attachmentKey(include.collection), linked);
515
- }
516
- for (const include of query?.pinIncludes ?? []) for (const record of records) {
517
- const pinned = await pinnedRecord(metadataFor(record), include.name, include.target);
518
- setAttachment(record, attachmentKey(include.name), pinned);
519
- }
520
- return records;
521
- }
522
- async deleteLinksForRecord(id) {
523
- const rows = await database.select("SELECT id, collections, ids FROM links");
524
- const affectedCollections = /* @__PURE__ */ new Set();
525
- for (const row of rows) if (linkIncludesRecord(row, this.name, id)) {
526
- const [firstCollection, secondCollection] = decodePair(rowValue(row, "collections"));
527
- affectedCollections.add(firstCollection);
528
- affectedCollections.add(secondCollection);
529
- await database.execute("DELETE FROM links WHERE id = ?", [rowValue(row, "id")]);
530
- }
531
- return affectedCollections;
532
- }
533
- async deletePinsForRecord(id) {
534
- const rows = await database.select(`SELECT sourceCollection, targetCollection FROM pins
535
- WHERE (sourceCollection = ? AND sourceId = ?)
536
- OR (targetCollection = ? AND targetId = ?)`, [
537
- this.name,
538
- id,
539
- this.name,
540
- id
541
- ]);
542
- const affectedCollections = /* @__PURE__ */ new Set();
543
- for (const row of rows) {
544
- affectedCollections.add(rowValue(row, "sourceCollection"));
545
- affectedCollections.add(rowValue(row, "targetCollection"));
546
- }
547
- await database.execute(`DELETE FROM pins
548
- WHERE (sourceCollection = ? AND sourceId = ?)
549
- OR (targetCollection = ? AND targetId = ?)`, [
550
- this.name,
551
- id,
552
- this.name,
553
- id
554
- ]);
555
- return affectedCollections;
556
- }
557
- };
558
- function collection(name, shape) {
559
- return new Collection(name, shape);
560
- }
561
- async function areLinked(first, second) {
562
- await initializeCollectionSchema();
563
- const row = storedLinkFor(first, second);
564
- return await database.get("SELECT id FROM links WHERE id = ?", [row.id]) !== void 0;
565
- }
566
- async function linkedRecords(source, target) {
567
- await initializeCollectionSchema();
568
- const rows = await database.select("SELECT collections, ids FROM links");
569
- const records = [];
570
- for (const row of rows) {
571
- const id = linkedIdFromRow(row, source, target.name);
572
- if (!id) continue;
573
- const record = await target.get(id);
574
- if (record) records.push(record);
575
- }
576
- return records;
577
- }
578
- async function pinnedRecord(source, name, target) {
579
- await initializeCollectionSchema();
580
- const row = await database.get(`SELECT targetId FROM pins
581
- WHERE sourceCollection = ?
582
- AND sourceId = ?
583
- AND name = ?
584
- AND targetCollection = ?`, [
585
- source.collection.name,
586
- source.id,
587
- name,
588
- target.name
589
- ]);
590
- if (!row) return;
591
- return target.get(rowValue(row, "targetId"));
592
- }
593
- async function link(first, second, third, fourth) {
594
- const firstReference = resolveRecordReference(first, typeof second === "string" ? second : void 0);
595
- const secondReference = third ? resolveRecordReference(third, fourth) : resolveRecordReference(second);
596
- const row = storedLinkFor(firstReference, secondReference);
597
- await initializeCollectionSchema();
598
- await database.execute("INSERT OR IGNORE INTO links (id, collections, ids, createdAt) VALUES (?, ?, ?, ?)", [
599
- row.id,
600
- row.collections,
601
- row.ids,
602
- (/* @__PURE__ */ new Date()).toISOString()
603
- ]);
604
- await notifyCollections(firstReference.collection.name, secondReference.collection.name);
605
- }
606
- async function unlink(first, second, third, fourth) {
607
- const firstReference = resolveRecordReference(first, typeof second === "string" ? second : void 0);
608
- const secondReference = third ? resolveRecordReference(third, fourth) : resolveRecordReference(second);
609
- const row = storedLinkFor(firstReference, secondReference);
610
- await initializeCollectionSchema();
611
- await database.execute("DELETE FROM links WHERE id = ?", [row.id]);
612
- await notifyCollections(firstReference.collection.name, secondReference.collection.name);
613
- }
614
- async function isLinked(first, second, third, fourth) {
615
- return areLinked(resolveRecordReference(first, typeof second === "string" ? second : void 0), third ? resolveRecordReference(third, fourth) : resolveRecordReference(second));
616
- }
617
- async function pin(source, second, third, fourth, fifth) {
618
- if (source instanceof Collection) {
619
- if (typeof third !== "string" || !fourth || !fifth) throw new Error("Expected source id, pin name, target collection, and target id");
620
- const sourceRecord$1 = resolveRecordReference(source, second);
621
- const targetRecord = resolveRecordReference(fourth, fifth);
622
- await sourceRecord$1.collection.pin(sourceRecord$1.id, third, targetRecord.collection, targetRecord.id);
623
- return;
624
- }
625
- if (typeof third !== "object") throw new Error("Expected a target record");
626
- const sourceRecord = metadataFor(source);
627
- await sourceRecord.collection.pin(sourceRecord.id, second, third);
628
- }
629
- async function unpin(source, second, third) {
630
- if (source instanceof Collection) {
631
- if (!third) throw new Error("Expected source id and pin name");
632
- await source.unpin(second, third);
633
- return;
634
- }
635
- const sourceRecord = metadataFor(source);
636
- await sourceRecord.collection.unpin(sourceRecord.id, second);
637
- }
638
- async function isPinned(source, second, third, fourth, fifth) {
639
- const sourceRecord = source instanceof Collection ? resolveRecordReference(source, second) : metadataFor(source);
640
- const name = source instanceof Collection ? String(third) : second;
641
- const targetRecord = source instanceof Collection ? resolveRecordReference(fourth, fifth) : resolveRecordReference(third);
642
- await initializeCollectionSchema();
643
- return await database.get(`SELECT targetId FROM pins
644
- WHERE sourceCollection = ?
645
- AND sourceId = ?
646
- AND name = ?
647
- AND targetCollection = ?
648
- AND targetId = ?`, [
649
- sourceRecord.collection.name,
650
- sourceRecord.id,
651
- name,
652
- targetRecord.collection.name,
653
- targetRecord.id
654
- ]) !== void 0;
655
- }
656
- var CollectionQuery = class {
657
- joins = [];
658
- joinIncludes = [];
659
- pinIncludes = [];
660
- cachedStore;
661
- constructor(collection$1) {
662
- this.collection = collection$1;
663
- }
664
- join(value, id) {
665
- if (value instanceof Collection) {
666
- if (id) {
667
- this.joins.push({
668
- kind: "id",
669
- collection: value,
670
- id
671
- });
672
- return this;
673
- }
674
- this.joinIncludes.push({ collection: value });
675
- return this;
676
- }
677
- this.joins.push({
678
- kind: "record",
679
- record: value
680
- });
681
- return this;
682
- }
683
- with(name, target) {
684
- this.pinIncludes.push({
685
- name,
686
- target
687
- });
688
- return this;
689
- }
690
- get() {
691
- return this.store().get();
692
- }
693
- subscribe(listener) {
694
- return this.store().subscribe(listener);
695
- }
696
- store() {
697
- this.cachedStore ??= this.collection.queryStore({
698
- joins: this.joins,
699
- joinIncludes: this.joinIncludes,
700
- pinIncludes: this.pinIncludes
701
- });
702
- return this.cachedStore;
703
- }
704
- };
705
- var QueryBuilder = class {
706
- from(collection$1) {
707
- return new CollectionQuery(collection$1);
708
- }
709
- };
710
- function useQuery(query) {
711
- return useStore(query(new QueryBuilder()));
712
- }
713
-
714
- //#endregion
715
- //#region src/state/setting.ts
716
- function readSettingValue(key, fallback) {
717
- const value = NSUserDefaults.standardUserDefaults.objectForKey(key);
718
- return value === null || value === void 0 ? fallback : value;
719
- }
720
- function writeSettingValue(key, value) {
721
- const userDefaults = NSUserDefaults.standardUserDefaults;
722
- if (value === void 0) {
723
- userDefaults.removeObjectForKey(key);
724
- return;
725
- }
726
- userDefaults.setObjectForKey(value, key);
727
- }
728
- function setting(key, initialValue) {
729
- const store = new LiveStore(readSettingValue(key, initialValue));
730
- return {
731
- get: store.get.bind(store),
732
- subscribe: store.subscribe.bind(store),
733
- set(value) {
734
- writeSettingValue(key, value);
735
- store.set(value);
736
- },
737
- update(updater) {
738
- this.set(updater(store.get()));
739
- }
740
- };
741
- }
742
- function useSetting(value) {
743
- return useStore(value);
744
- }
745
-
746
- //#endregion
747
- export { Collection, LiveStore, QueryBuilder, atom, collection, isLinked, isPinned, link, pin, setting, unlink, unpin, useAtom, useQuery, useSetting, useStore };
6
+ export { Collection, LiveStore, atom, collection, isLinked, link, setting, unlink, useAtom, useField, useList, useSetting, useStore, useView };