@seedprotocol/sdk 0.1.12 → 0.1.14
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/bin.js +16 -15
- package/dist/bin.js.map +1 -1
- package/dist/{events-C7mxVpb2.js → events-DY-qRoqO.js} +1352 -1241
- package/dist/events-DY-qRoqO.js.map +1 -0
- package/dist/{index-DiskIvP7.js → index-Do5zWGFy.js} +19 -17
- package/dist/index-Do5zWGFy.js.map +1 -0
- package/dist/main.js +16 -15
- package/dist/main.js.map +1 -1
- package/dist/{seed-BYEGj3gH.js → seed-BJtzMyfP.js} +20 -18
- package/dist/seed-BJtzMyfP.js.map +1 -0
- package/dist/{seed-XYWpo5oW.js → seed-CVV8OMEg.js} +2 -2
- package/dist/{seed-XYWpo5oW.js.map → seed-CVV8OMEg.js.map} +1 -1
- package/dist/{seed-BTpkUOtG.js → seed-Ch6JPrtQ.js} +20 -18
- package/dist/seed-Ch6JPrtQ.js.map +1 -0
- package/dist/{seed.schema.config-WWLDCsw_.js → seed.schema.config-t5AiIDm_.js} +16 -15
- package/dist/seed.schema.config-t5AiIDm_.js.map +1 -0
- package/dist/types/src/browser/index.d.ts +0 -1
- package/dist/types/src/browser/index.d.ts.map +1 -1
- package/dist/types/src/browser/react/db.d.ts +4 -0
- package/dist/types/src/browser/react/db.d.ts.map +1 -0
- package/dist/types/src/browser/react/index.d.ts +4 -53
- package/dist/types/src/browser/react/index.d.ts.map +1 -1
- package/dist/types/src/browser/react/item.d.ts +36 -0
- package/dist/types/src/browser/react/item.d.ts.map +1 -0
- package/dist/types/src/browser/react/property.d.ts +12 -0
- package/dist/types/src/browser/react/property.d.ts.map +1 -0
- package/dist/types/src/browser/react/services.d.ts +30 -0
- package/dist/types/src/browser/react/services.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/shared/helpers/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/events-C7mxVpb2.js.map +0 -1
- package/dist/index-DiskIvP7.js.map +0 -1
- package/dist/seed-BTpkUOtG.js.map +0 -1
- package/dist/seed-BYEGj3gH.js.map +0 -1
- package/dist/seed.schema.config-WWLDCsw_.js.map +0 -1
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useImmer } from 'use-immer';
|
|
2
|
+
import { sql, count, max, eq, and, or, isNull, relations } from 'drizzle-orm';
|
|
3
|
+
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
4
|
+
import debug from 'debug';
|
|
3
5
|
import { fromCallback, setup, assign, createActor, waitFor, emit } from 'xstate';
|
|
4
6
|
import { BehaviorSubject } from 'rxjs';
|
|
5
7
|
import { fs, configureSingle } from '@zenfs/core';
|
|
6
|
-
import { sql, count, max, eq, and, or, isNull, relations } from 'drizzle-orm';
|
|
7
|
-
import { drizzle } from 'drizzle-orm/sqlite-proxy';
|
|
8
|
-
import debug from 'debug';
|
|
9
|
-
import 'dayjs';
|
|
10
|
-
import { customAlphabet } from 'nanoid';
|
|
11
|
-
import * as nanoIdDictionary from 'nanoid-dictionary';
|
|
12
8
|
import { startCase, debounce, camelCase, orderBy } from 'lodash-es';
|
|
13
|
-
import {
|
|
9
|
+
import { immerable, produce } from 'immer';
|
|
10
|
+
import pluralize from 'pluralize';
|
|
11
|
+
import { useSelector } from '@xstate/react';
|
|
12
|
+
import { orderBy as orderBy$1 } from 'lodash';
|
|
13
|
+
import { createBrowserInspector } from '@statelyai/inspect';
|
|
14
|
+
import 'reflect-metadata';
|
|
15
|
+
import { Type } from '@sinclair/typebox';
|
|
16
|
+
import Arweave from 'arweave';
|
|
17
|
+
import { WebAccess } from '@zenfs/dom';
|
|
18
|
+
import { drizzle } from 'drizzle-orm/sqlite-proxy';
|
|
14
19
|
import { QueryClient } from '@tanstack/react-query';
|
|
15
20
|
import { GraphQLClient } from 'graphql-request';
|
|
16
21
|
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
|
|
17
22
|
import { persistQueryClient } from '@tanstack/react-query-persist-client';
|
|
18
23
|
import path, { basename } from 'path';
|
|
19
|
-
import {
|
|
20
|
-
import
|
|
21
|
-
import {
|
|
22
|
-
import
|
|
23
|
-
import Arweave from 'arweave';
|
|
24
|
-
import { useImmer } from 'use-immer';
|
|
25
|
-
import { useSelector } from '@xstate/react';
|
|
24
|
+
import { sqliteTable, text, int, blob, check, unique } from 'drizzle-orm/sqlite-core';
|
|
25
|
+
import 'dayjs';
|
|
26
|
+
import { customAlphabet } from 'nanoid';
|
|
27
|
+
import * as nanoIdDictionary from 'nanoid-dictionary';
|
|
26
28
|
import EventEmitter from 'eventemitter3';
|
|
27
29
|
|
|
28
30
|
const isNode = () => {
|
|
@@ -213,14 +215,14 @@ const getSqlite = async () => {
|
|
|
213
215
|
}
|
|
214
216
|
};
|
|
215
217
|
|
|
216
|
-
const logger$
|
|
218
|
+
const logger$g = debug('app:db:actors');
|
|
217
219
|
let seedDb;
|
|
218
220
|
let appDb;
|
|
219
221
|
let sdkConfigDb;
|
|
220
222
|
let sqliteWasmClient$1;
|
|
221
223
|
const checkStatus = fromCallback(({ sendBack, input: { context } }) => {
|
|
222
224
|
const { dbName, dirName } = context;
|
|
223
|
-
logger$
|
|
225
|
+
logger$g('[db/actors] checkStatus context', context);
|
|
224
226
|
const pathToDir = `${BROWSER_FS_TOP_DIR}/${dirName}`;
|
|
225
227
|
const pathToDbDir = `${pathToDir}/db`;
|
|
226
228
|
const pathToDb = `${pathToDbDir}/${dbName}.sqlite3`;
|
|
@@ -251,7 +253,7 @@ const checkStatus = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
251
253
|
});
|
|
252
254
|
});
|
|
253
255
|
const connectToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
254
|
-
logger$
|
|
256
|
+
logger$g('[db/actors] connectToDb context', context);
|
|
255
257
|
const { dbName, pathToDir } = context;
|
|
256
258
|
let isConnecting = false;
|
|
257
259
|
let dbId;
|
|
@@ -266,16 +268,16 @@ const connectToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
266
268
|
}
|
|
267
269
|
//@ts-ignore
|
|
268
270
|
response = yield sqliteWasmClient$1('config-get', {});
|
|
269
|
-
logger$
|
|
270
|
-
logger$
|
|
271
|
+
logger$g(response);
|
|
272
|
+
logger$g('Running SQLite3 version', response.result.version.libVersion);
|
|
271
273
|
//@ts-ignore
|
|
272
274
|
response = yield sqliteWasmClient$1('open', {
|
|
273
275
|
filename: `file:${pathToDir}/db/${dbName}.sqlite3?vfs=opfs`,
|
|
274
276
|
});
|
|
275
|
-
logger$
|
|
277
|
+
logger$g(response);
|
|
276
278
|
dbId = response.dbId;
|
|
277
279
|
// logger(`dbId: ${dbId}`)
|
|
278
|
-
logger$
|
|
280
|
+
logger$g('OPFS is available, created persisted database at', response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'));
|
|
279
281
|
});
|
|
280
282
|
const interval = setInterval(() => {
|
|
281
283
|
// TODO: Add a timeout
|
|
@@ -395,7 +397,7 @@ const dbExec = (dbId_1, params_1, sql_1, dbName_1, ...args_1) => __awaiter(void
|
|
|
395
397
|
});
|
|
396
398
|
const migrate = fromCallback(({ sendBack, input: { context } }) => {
|
|
397
399
|
const { pathToDbDir, dirName, dbId, dbName } = context;
|
|
398
|
-
logger$
|
|
400
|
+
logger$g('[db/actors] migrate context', context);
|
|
399
401
|
const schemaGlobString = `${BROWSER_FS_TOP_DIR}/${dirName}/schema/*`;
|
|
400
402
|
const isSeedDb = dbName === DB_NAME_SEED;
|
|
401
403
|
const isAppDb = dbName === DB_NAME_APP;
|
|
@@ -675,7 +677,7 @@ const initialize$3 = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
675
677
|
}
|
|
676
678
|
});
|
|
677
679
|
|
|
678
|
-
const logger$
|
|
680
|
+
const logger$f = debug('app:shared:helpers');
|
|
679
681
|
const { alphanumeric } = nanoIdDictionary;
|
|
680
682
|
const generateId = () => {
|
|
681
683
|
return customAlphabet(alphanumeric, 10)();
|
|
@@ -738,7 +740,7 @@ const convertTxIdToImageSrc = (txId) => __awaiter(void 0, void 0, void 0, functi
|
|
|
738
740
|
const imageFilePath = `/files/images/${txId}`;
|
|
739
741
|
const fileExists = yield fs.promises.exists(imageFilePath);
|
|
740
742
|
if (!fileExists) {
|
|
741
|
-
logger$
|
|
743
|
+
logger$f(`[ItemView] [updateImageSrc] ${imageFilePath} does not exist`);
|
|
742
744
|
return;
|
|
743
745
|
}
|
|
744
746
|
const uint = yield fs.promises.readFile(imageFilePath);
|
|
@@ -1517,7 +1519,7 @@ const getAddressesFromDb = () => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
1517
1519
|
return JSON.parse(addressArrayString);
|
|
1518
1520
|
});
|
|
1519
1521
|
|
|
1520
|
-
const logger$
|
|
1522
|
+
const logger$e = debug('app:property:actors:hydrateFromDb');
|
|
1521
1523
|
const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
1522
1524
|
const { seedUid, seedLocalId, propertyName: propertyNameRaw, propertyValue, propertyRecordSchema, itemModelName, } = context;
|
|
1523
1525
|
let propertyName = propertyNameRaw;
|
|
@@ -1585,23 +1587,23 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1585
1587
|
const firstRow = rows[0];
|
|
1586
1588
|
const { localId, uid, propertyName: propertyNameFromDb, propertyValue: propertyValueFromDb, seedLocalId: seedLocalIdFromDb, seedUid: seedUidFromDb, schemaUid: schemaUidFromDb, refResolvedValue, refResolvedDisplayValue, } = firstRow;
|
|
1587
1589
|
if (propertyName && !propertyNameFromDb) {
|
|
1588
|
-
logger$
|
|
1590
|
+
logger$e(`Property name from code is ${propertyName} but has not value in db ${propertyNameFromDb} for Property.${localId}`);
|
|
1589
1591
|
}
|
|
1590
1592
|
if (propertyName &&
|
|
1591
1593
|
propertyNameFromDb &&
|
|
1592
1594
|
!propertyNameFromDb.includes(propertyName) &&
|
|
1593
1595
|
!propertyName.includes(propertyNameFromDb) &&
|
|
1594
1596
|
propertyNameFromDb !== propertyName) {
|
|
1595
|
-
logger$
|
|
1597
|
+
logger$e(`Property name from db ${propertyNameFromDb} does not match property name ${propertyName} for Property.${localId}`);
|
|
1596
1598
|
}
|
|
1597
1599
|
if (propertyValue && propertyValueFromDb !== propertyValue) {
|
|
1598
|
-
logger$
|
|
1600
|
+
logger$e(`Property value from db ${propertyValueFromDb} does not match property value ${propertyValue} for Property.${localId}`);
|
|
1599
1601
|
}
|
|
1600
1602
|
if (seedLocalIdFromDb !== seedLocalId) {
|
|
1601
|
-
logger$
|
|
1603
|
+
logger$e(`Seed local id from db ${seedLocalIdFromDb} does not match seed local id ${seedLocalId} for Property.${localId}`);
|
|
1602
1604
|
}
|
|
1603
1605
|
if (seedUidFromDb !== seedUid) {
|
|
1604
|
-
logger$
|
|
1606
|
+
logger$e(`Seed uid from db ${seedUidFromDb} does not match seed uid ${seedUid} for Property.${localId}`);
|
|
1605
1607
|
}
|
|
1606
1608
|
sendBack({
|
|
1607
1609
|
type: 'updateContext',
|
|
@@ -1616,7 +1618,7 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1616
1618
|
renderValue: refResolvedDisplayValue,
|
|
1617
1619
|
});
|
|
1618
1620
|
if (propertyNameFromDb === 'storageTransactionId') {
|
|
1619
|
-
const { Item } = yield import('./index-
|
|
1621
|
+
const { Item } = yield import('./index-Do5zWGFy.js');
|
|
1620
1622
|
const item = yield Item.find({
|
|
1621
1623
|
seedLocalId,
|
|
1622
1624
|
modelName: itemModelName,
|
|
@@ -1634,7 +1636,7 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1634
1636
|
const renderValue = yield fs.promises
|
|
1635
1637
|
.readFile(htmlFilePath, 'utf8')
|
|
1636
1638
|
.catch((error) => {
|
|
1637
|
-
logger$
|
|
1639
|
+
logger$e('Error reading html file', error);
|
|
1638
1640
|
});
|
|
1639
1641
|
property
|
|
1640
1642
|
.getService()
|
|
@@ -1715,7 +1717,7 @@ const getVersionData = (_a) => __awaiter(void 0, [_a], void 0, function* ({ seed
|
|
|
1715
1717
|
|
|
1716
1718
|
const eventEmitter = new EventEmitter();
|
|
1717
1719
|
|
|
1718
|
-
const logger$
|
|
1720
|
+
const logger$d = debug('app:write');
|
|
1719
1721
|
const sendItemUpdateEvent = ({ modelName, seedLocalId, seedUid }) => {
|
|
1720
1722
|
if (!modelName || (!seedLocalId && !seedUid)) {
|
|
1721
1723
|
return;
|
|
@@ -1793,7 +1795,7 @@ const deleteItem = (_a) => __awaiter(void 0, [_a], void 0, function* ({ seedLoca
|
|
|
1793
1795
|
});
|
|
1794
1796
|
const updateItemPropertyValue = (_a) => __awaiter(void 0, [_a], void 0, function* ({ propertyLocalId, propertyName, newValue, seedUid, seedLocalId, modelName, refSeedType, refResolvedValue, refResolvedDisplayValue, versionLocalId, versionUid, schemaUid, }) {
|
|
1795
1797
|
if (!propertyLocalId && !seedLocalId) {
|
|
1796
|
-
logger$
|
|
1798
|
+
logger$d(`[db/write] [updateItemPropertyValue] no propertyLocalId or seedLocalId for property: ${propertyName}`);
|
|
1797
1799
|
return;
|
|
1798
1800
|
}
|
|
1799
1801
|
let safeNewValue = newValue;
|
|
@@ -1832,7 +1834,7 @@ const updateItemPropertyValue = (_a) => __awaiter(void 0, [_a], void 0, function
|
|
|
1832
1834
|
const schemaUid = mostRecentRecord[9];
|
|
1833
1835
|
const easDataType = mostRecentRecord[10];
|
|
1834
1836
|
if (propertyValueFromDb === newValue) {
|
|
1835
|
-
logger$
|
|
1837
|
+
logger$d(`[db/write] [updateItemPropertyValue] value is the same as most recent record for property: ${propertyNameFromDb}`);
|
|
1836
1838
|
return;
|
|
1837
1839
|
}
|
|
1838
1840
|
// This means we already have a local-only record so we should just update that one
|
|
@@ -2247,7 +2249,7 @@ const setModel = (modelName, model) => {
|
|
|
2247
2249
|
};
|
|
2248
2250
|
|
|
2249
2251
|
var _a$1;
|
|
2250
|
-
const logger$
|
|
2252
|
+
const logger$c = debug('app:property:class');
|
|
2251
2253
|
const namesThatEndWithId = [];
|
|
2252
2254
|
class ItemProperty {
|
|
2253
2255
|
// private constructor(localIdOrUid) {
|
|
@@ -2295,7 +2297,7 @@ class ItemProperty {
|
|
|
2295
2297
|
serviceInput.propertyValue = JSON.parse(propertyValue);
|
|
2296
2298
|
}
|
|
2297
2299
|
catch (e) {
|
|
2298
|
-
logger$
|
|
2300
|
+
logger$c('List property value is not JSON', e);
|
|
2299
2301
|
}
|
|
2300
2302
|
}
|
|
2301
2303
|
const propertyNameSingular = pluralize(propertyName, 1);
|
|
@@ -2357,7 +2359,7 @@ class ItemProperty {
|
|
|
2357
2359
|
this._service.start();
|
|
2358
2360
|
}
|
|
2359
2361
|
_updateResponseListener(event) {
|
|
2360
|
-
logger$
|
|
2362
|
+
logger$c(`[ItemProperty] [_updateResponseListener] [${this.itemModelName}.${this.seedLocalId}] ${this.propertyName} event`, event);
|
|
2361
2363
|
}
|
|
2362
2364
|
static create(props) {
|
|
2363
2365
|
const { propertyName, seedLocalId, uid } = props;
|
|
@@ -2493,7 +2495,7 @@ class ItemProperty {
|
|
|
2493
2495
|
}
|
|
2494
2496
|
unload() {
|
|
2495
2497
|
this._service.stop();
|
|
2496
|
-
logger$
|
|
2498
|
+
logger$c(`[XXXXXX] [ItemProperty] [${this.seedLocalId}] [unload] removing listener`, this._updateResponseEvent);
|
|
2497
2499
|
eventEmitter.removeListener(this._updateResponseEvent, this._updateResponseListener);
|
|
2498
2500
|
}
|
|
2499
2501
|
}
|
|
@@ -3782,7 +3784,7 @@ const getPropertiesForSeed = (seedLocalId, seedUid) => __awaiter(void 0, void 0,
|
|
|
3782
3784
|
return propertiesData;
|
|
3783
3785
|
});
|
|
3784
3786
|
|
|
3785
|
-
const logger$
|
|
3787
|
+
const logger$b = debug('app:db:queries:getItem');
|
|
3786
3788
|
const getItemDataFromDb = (_a) => __awaiter(void 0, [_a], void 0, function* ({ modelName, seedLocalId, seedUid, }) {
|
|
3787
3789
|
if (!seedLocalId && !seedUid) {
|
|
3788
3790
|
throw new Error('[db/queries] [getItem] no seedLocalId or seedUid');
|
|
@@ -3790,7 +3792,7 @@ const getItemDataFromDb = (_a) => __awaiter(void 0, [_a], void 0, function* ({ m
|
|
|
3790
3792
|
if (seedUid && !seedLocalId) {
|
|
3791
3793
|
const seedData = yield getSeedData({ seedUid });
|
|
3792
3794
|
if (!seedData) {
|
|
3793
|
-
logger$
|
|
3795
|
+
logger$b('[db/queries] [getItem] no seedData seedUid', seedUid);
|
|
3794
3796
|
return;
|
|
3795
3797
|
}
|
|
3796
3798
|
seedLocalId = seedData.localId;
|
|
@@ -4218,7 +4220,7 @@ const fetchDbData = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
4218
4220
|
return () => { };
|
|
4219
4221
|
});
|
|
4220
4222
|
|
|
4221
|
-
const logger$
|
|
4223
|
+
const logger$a = debug('app:allItemsActors:fetchSeeds');
|
|
4222
4224
|
const fetchSeeds = fromCallback(({ sendBack, input: { context } }) => {
|
|
4223
4225
|
const { queryVariables, modelName } = context;
|
|
4224
4226
|
if (!queryVariables) {
|
|
@@ -4228,7 +4230,7 @@ const fetchSeeds = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
4228
4230
|
const _fetchSeeds = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4229
4231
|
const queryKey = [`getSeeds${modelName}`];
|
|
4230
4232
|
const cachedResults = queryClient.getQueryData(queryKey);
|
|
4231
|
-
logger$
|
|
4233
|
+
logger$a(`[allItemsActors] [fetchSeeds] cachedResults ${Date.now()}`, cachedResults);
|
|
4232
4234
|
const results = yield queryClient.fetchQuery({
|
|
4233
4235
|
queryKey,
|
|
4234
4236
|
queryFn: () => __awaiter(void 0, void 0, void 0, function* () { return easClient.request(GET_SEEDS, queryVariables); }),
|
|
@@ -4799,782 +4801,1206 @@ const getArweave = () => {
|
|
|
4799
4801
|
});
|
|
4800
4802
|
};
|
|
4801
4803
|
|
|
4802
|
-
const logger$
|
|
4803
|
-
const
|
|
4804
|
-
const
|
|
4805
|
-
const
|
|
4806
|
-
|
|
4807
|
-
if (isNode()) {
|
|
4808
|
-
environment = 'node';
|
|
4809
|
-
}
|
|
4810
|
-
if (isReactNative()) {
|
|
4811
|
-
environment = 'react-native';
|
|
4812
|
-
}
|
|
4813
|
-
let internalSubscription;
|
|
4814
|
-
if (environment === 'browser' && models) {
|
|
4815
|
-
const _initFileSystem = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4816
|
-
return;
|
|
4817
|
-
// return new Promise((resolve) => {
|
|
4818
|
-
// })
|
|
4819
|
-
});
|
|
4820
|
-
const _initInternal = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4821
|
-
return new Promise((resolve) => {
|
|
4822
|
-
internalSubscription = internalService.subscribe((snapshot) => {
|
|
4823
|
-
logger$7('[sdk] [internal] snapshot', snapshot);
|
|
4824
|
-
if (snapshot.value === 'ready') {
|
|
4825
|
-
resolve();
|
|
4826
|
-
}
|
|
4827
|
-
});
|
|
4828
|
-
internalService.send({ type: 'init', endpoints, addresses });
|
|
4829
|
-
});
|
|
4830
|
-
});
|
|
4831
|
-
_initFileSystem().then(() => {
|
|
4832
|
-
logger$7('[global/actors] File system initialized');
|
|
4833
|
-
});
|
|
4834
|
-
_initInternal().then(() => {
|
|
4835
|
-
logger$7('[global/actors] Internal initialized');
|
|
4836
|
-
sendBack({ type: GLOBAL_INITIALIZING_INTERNAL_SERVICE_READY });
|
|
4837
|
-
internalSubscription === null || internalSubscription === void 0 ? void 0 : internalSubscription.unsubscribe();
|
|
4838
|
-
});
|
|
4839
|
-
// _initEas().then(() => {
|
|
4840
|
-
// logger('EAS initialized')
|
|
4841
|
-
// })
|
|
4842
|
-
}
|
|
4843
|
-
sendBack({ type: GLOBAL_INITIALIZING_SEND_CONFIG, environment });
|
|
4844
|
-
return () => {
|
|
4845
|
-
internalSubscription === null || internalSubscription === void 0 ? void 0 : internalSubscription.unsubscribe();
|
|
4846
|
-
};
|
|
4847
|
-
});
|
|
4848
|
-
const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
4849
|
-
const { models: models$1 } = context;
|
|
4850
|
-
const _addModelsToDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4851
|
-
var _a;
|
|
4852
|
-
const sdkConfigDb = getSdkDb();
|
|
4853
|
-
if (!models$1) {
|
|
4804
|
+
const logger$9 = debug('app:react:db');
|
|
4805
|
+
const useDbsAreReady = () => {
|
|
4806
|
+
const [dbsAreReady, setDbsAreReady] = useState(false);
|
|
4807
|
+
const update = useCallback(() => {
|
|
4808
|
+
if (dbsAreReady) {
|
|
4854
4809
|
return;
|
|
4855
4810
|
}
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
const
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
.
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4811
|
+
setDbsAreReady(true);
|
|
4812
|
+
}, []);
|
|
4813
|
+
useEffect(() => {
|
|
4814
|
+
let globalSubscription;
|
|
4815
|
+
let internalSubscription;
|
|
4816
|
+
const _waitForDbs = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4817
|
+
const globalService = getGlobalService();
|
|
4818
|
+
const internalService = globalService.getSnapshot().context.internalService;
|
|
4819
|
+
if (!internalService) {
|
|
4820
|
+
logger$9('[useDbsAreReady] [useEffect] no internalService');
|
|
4821
|
+
globalSubscription = globalService.subscribe(({ context }) => {
|
|
4822
|
+
if (!internalSubscription && context && context.internalService) {
|
|
4823
|
+
globalSubscription === null || globalSubscription === void 0 ? void 0 : globalSubscription.unsubscribe();
|
|
4824
|
+
internalSubscription = context.internalService.subscribe((snapshot) => {
|
|
4825
|
+
if (snapshot.value === 'ready') {
|
|
4826
|
+
update();
|
|
4827
|
+
internalSubscription === null || internalSubscription === void 0 ? void 0 : internalSubscription.unsubscribe();
|
|
4828
|
+
}
|
|
4829
|
+
});
|
|
4830
|
+
}
|
|
4870
4831
|
});
|
|
4871
|
-
|
|
4872
|
-
const foundModels = yield sdkConfigDb
|
|
4873
|
-
.select({
|
|
4874
|
-
id: models.id,
|
|
4875
|
-
name: models.name,
|
|
4876
|
-
uid: modelUids.uid,
|
|
4877
|
-
})
|
|
4878
|
-
.from(models)
|
|
4879
|
-
.leftJoin(modelUids, eq(models.id, modelUids.modelId))
|
|
4880
|
-
.where(eq(models.name, modelName))
|
|
4881
|
-
.limit(1);
|
|
4882
|
-
foundModel = foundModels[0];
|
|
4883
|
-
}
|
|
4884
|
-
if (foundModelsQuery && foundModelsQuery.length > 0) {
|
|
4885
|
-
foundModel = foundModelsQuery[0];
|
|
4832
|
+
return;
|
|
4886
4833
|
}
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4834
|
+
const currentState = internalService.getSnapshot().value;
|
|
4835
|
+
if (currentState === 'ready') {
|
|
4836
|
+
update();
|
|
4837
|
+
return;
|
|
4890
4838
|
}
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4839
|
+
internalSubscription = internalService.subscribe((snapshot) => {
|
|
4840
|
+
if (snapshot.value === 'ready') {
|
|
4841
|
+
update();
|
|
4842
|
+
internalSubscription === null || internalSubscription === void 0 ? void 0 : internalSubscription.unsubscribe();
|
|
4843
|
+
}
|
|
4894
4844
|
});
|
|
4895
|
-
}
|
|
4896
|
-
if (!hasModelsInDb) {
|
|
4897
|
-
return false;
|
|
4898
|
-
}
|
|
4899
|
-
const schemaDefs = Array.from(schemaDefsByModelName.values()).map(({ schemaDef }) => schemaDef);
|
|
4900
|
-
const { schemas } = yield queryClient.fetchQuery({
|
|
4901
|
-
queryKey: [`getSchemasVersion`],
|
|
4902
|
-
queryFn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
4903
|
-
return easClient.request(GET_SCHEMAS, {
|
|
4904
|
-
where: {
|
|
4905
|
-
schema: {
|
|
4906
|
-
in: schemaDefs,
|
|
4907
|
-
},
|
|
4908
|
-
},
|
|
4909
|
-
});
|
|
4910
|
-
}),
|
|
4911
4845
|
});
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
const modelId = (_a = Array.from(schemaDefsByModelName.values()).find(({ schemaDef }) => schemaDef === schema.schema)) === null || _a === void 0 ? void 0 : _a.dbId;
|
|
4917
|
-
if (!modelId) {
|
|
4918
|
-
throw new Error(`No modelId found for schema ${schema.schema}`);
|
|
4846
|
+
_waitForDbs();
|
|
4847
|
+
return () => {
|
|
4848
|
+
if (globalSubscription) {
|
|
4849
|
+
globalSubscription.unsubscribe();
|
|
4919
4850
|
}
|
|
4920
|
-
|
|
4921
|
-
.
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4851
|
+
if (internalSubscription) {
|
|
4852
|
+
internalSubscription.unsubscribe();
|
|
4853
|
+
}
|
|
4854
|
+
};
|
|
4855
|
+
}, []);
|
|
4856
|
+
return {
|
|
4857
|
+
dbsAreReady,
|
|
4858
|
+
};
|
|
4859
|
+
};
|
|
4860
|
+
|
|
4861
|
+
const finalStrings = ['idle', 'ready', 'done', 'success'];
|
|
4862
|
+
const getServiceName = (service) => {
|
|
4863
|
+
let name = 'actor';
|
|
4864
|
+
if (service && service.uniqueKey) {
|
|
4865
|
+
name = service.uniqueKey;
|
|
4866
|
+
}
|
|
4867
|
+
if (service && !service.uniqueKey && service.logic && service.logic.config) {
|
|
4868
|
+
name = getServiceUniqueKey(service);
|
|
4869
|
+
}
|
|
4870
|
+
return name;
|
|
4871
|
+
};
|
|
4872
|
+
const getServiceValue = (service) => {
|
|
4873
|
+
let value;
|
|
4874
|
+
if (service && service.getSnapshot() && service.getSnapshot().value) {
|
|
4875
|
+
value = service.getSnapshot().value;
|
|
4876
|
+
}
|
|
4877
|
+
if (getServiceName(service) === 'global') {
|
|
4878
|
+
if (value &&
|
|
4879
|
+
typeof value === 'object' &&
|
|
4880
|
+
Object.keys(value).length > 0 &&
|
|
4881
|
+
Object.keys(value)[0] === 'initialized') {
|
|
4882
|
+
value = 'ready';
|
|
4934
4883
|
}
|
|
4935
|
-
eventEmitter.emit('syncDbWithEas');
|
|
4936
|
-
return;
|
|
4937
|
-
});
|
|
4938
|
-
return () => { };
|
|
4939
|
-
});
|
|
4940
|
-
const getSchemaForModel = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
4941
|
-
const { modelName } = event;
|
|
4942
|
-
if (!modelName) {
|
|
4943
|
-
console.warn('No modelName found');
|
|
4944
|
-
return;
|
|
4945
4884
|
}
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4885
|
+
return value;
|
|
4886
|
+
};
|
|
4887
|
+
const getServiceUniqueKey = (service) => {
|
|
4888
|
+
if (!service || !service.logic || !service.logic.config) {
|
|
4949
4889
|
return;
|
|
4950
4890
|
}
|
|
4951
|
-
const
|
|
4952
|
-
if (!
|
|
4953
|
-
|
|
4891
|
+
const config = service.logic.config;
|
|
4892
|
+
if (!config.id) {
|
|
4893
|
+
return;
|
|
4954
4894
|
}
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
});
|
|
4959
|
-
|
|
4960
|
-
class SqliteConnectionManager {
|
|
4961
|
-
constructor(sqliteModule, idleTimeout = 300000) {
|
|
4962
|
-
// Default idle timeout: 5 minutes
|
|
4963
|
-
this.sqliteModule = sqliteModule;
|
|
4964
|
-
this.idleTimeout = idleTimeout;
|
|
4965
|
-
this.databases = {};
|
|
4966
|
-
this.idleTimers = {};
|
|
4895
|
+
let uniqueKey = config.id;
|
|
4896
|
+
if (config.id.includes('@seedSdk/')) {
|
|
4897
|
+
uniqueKey = config.id.match(/^.*@seedSdk\/(\w+)[\.\w]*/)[1];
|
|
4967
4898
|
}
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4899
|
+
const snapshot = service.getSnapshot();
|
|
4900
|
+
if (snapshot) {
|
|
4901
|
+
const context = snapshot.context;
|
|
4902
|
+
if (context && context.dbName) {
|
|
4903
|
+
uniqueKey = context.dbName;
|
|
4904
|
+
}
|
|
4905
|
+
if (context && context.modelNamePlural) {
|
|
4906
|
+
uniqueKey = context.modelNamePlural;
|
|
4907
|
+
}
|
|
4908
|
+
if (context && context.modelName) {
|
|
4909
|
+
uniqueKey = pluralize(context.modelName.toLowerCase());
|
|
4971
4910
|
}
|
|
4972
|
-
this.idleTimers[dbName] = setTimeout(() => {
|
|
4973
|
-
this.closeConnection(dbName);
|
|
4974
|
-
}, this.idleTimeout);
|
|
4975
4911
|
}
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
if (this.databases[dbName]) {
|
|
4999
|
-
this.databases[dbName].close();
|
|
5000
|
-
delete this.databases[dbName];
|
|
5001
|
-
if (this.idleTimers[dbName]) {
|
|
5002
|
-
clearTimeout(this.idleTimers[dbName]);
|
|
5003
|
-
delete this.idleTimers[dbName];
|
|
4912
|
+
return uniqueKey;
|
|
4913
|
+
};
|
|
4914
|
+
const useServices = () => {
|
|
4915
|
+
const [actors, setActors] = useState([]);
|
|
4916
|
+
const [percentComplete, setPercentComplete] = useState(5);
|
|
4917
|
+
const actorsMap = new Map();
|
|
4918
|
+
useEffect(() => {
|
|
4919
|
+
const globalServiceListener = (event) => {
|
|
4920
|
+
if (event.actorRef &&
|
|
4921
|
+
event.actorRef.logic &&
|
|
4922
|
+
event.actorRef.logic.config) {
|
|
4923
|
+
const uniqueKey = getServiceUniqueKey(event.actorRef);
|
|
4924
|
+
if (!uniqueKey) {
|
|
4925
|
+
return;
|
|
4926
|
+
}
|
|
4927
|
+
event.actorRef.uniqueKey = uniqueKey;
|
|
4928
|
+
actorsMap.set(uniqueKey, event.actorRef);
|
|
4929
|
+
let actorsArray = Array.from(actorsMap.values());
|
|
4930
|
+
actorsArray = orderBy$1(actorsArray, (a) => a.logic.config.id, ['asc']);
|
|
4931
|
+
setActors(produce(actors, (draft) => {
|
|
4932
|
+
return actorsArray;
|
|
4933
|
+
}));
|
|
5004
4934
|
}
|
|
4935
|
+
};
|
|
4936
|
+
eventEmitter.addListener('inspect.globalService', globalServiceListener);
|
|
4937
|
+
return () => {
|
|
4938
|
+
eventEmitter.removeListener('inspect.globalService', globalServiceListener);
|
|
4939
|
+
};
|
|
4940
|
+
}, []);
|
|
4941
|
+
useEffect(() => {
|
|
4942
|
+
const globalService = actors.find((actor) => getServiceName(actor) === 'global');
|
|
4943
|
+
const internalService = actors.find((actor) => getServiceName(actor) === 'internal');
|
|
4944
|
+
if (!globalService || !internalService) {
|
|
4945
|
+
return;
|
|
5005
4946
|
}
|
|
5006
|
-
|
|
5007
|
-
|
|
4947
|
+
if (getServiceValue(globalService) === 'ready' &&
|
|
4948
|
+
getServiceValue(internalService) === 'ready') {
|
|
4949
|
+
const denominator = actors.length;
|
|
4950
|
+
const finishedActors = actors.filter((actor) => {
|
|
4951
|
+
const value = getServiceValue(actor);
|
|
4952
|
+
return finalStrings.includes(value);
|
|
4953
|
+
});
|
|
4954
|
+
const numerator = finishedActors.length;
|
|
4955
|
+
const percentComplete = (numerator / denominator) * 100;
|
|
4956
|
+
setPercentComplete(percentComplete);
|
|
4957
|
+
}
|
|
4958
|
+
}, [actors]);
|
|
4959
|
+
return {
|
|
4960
|
+
services: actors,
|
|
4961
|
+
percentComplete,
|
|
4962
|
+
};
|
|
4963
|
+
};
|
|
4964
|
+
const useGlobalServiceStatus = () => {
|
|
4965
|
+
const globalService = getGlobalService();
|
|
4966
|
+
const status = useSelector(globalService, (snapshot) => {
|
|
4967
|
+
return snapshot.value;
|
|
4968
|
+
});
|
|
4969
|
+
const internalStatus = useSelector(globalService.getSnapshot().context.internalService, (snapshot) => {
|
|
4970
|
+
if (!snapshot) {
|
|
4971
|
+
return;
|
|
4972
|
+
}
|
|
4973
|
+
return snapshot.value;
|
|
4974
|
+
});
|
|
4975
|
+
useSelector(globalService, (snapshot) => {
|
|
4976
|
+
return snapshot.context.internalService;
|
|
4977
|
+
});
|
|
4978
|
+
return {
|
|
4979
|
+
status,
|
|
4980
|
+
internalStatus,
|
|
4981
|
+
};
|
|
4982
|
+
};
|
|
5008
4983
|
|
|
5009
|
-
const logger$
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
const
|
|
5015
|
-
const
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
}
|
|
5019
|
-
const
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
}
|
|
5024
|
-
yield fs.promises.mkdir(dirPath, { recursive: true });
|
|
5025
|
-
});
|
|
5026
|
-
let busy = false;
|
|
5027
|
-
const downloadFile = (url, localFilePath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5028
|
-
try {
|
|
5029
|
-
const response = yield fetch(url);
|
|
5030
|
-
const fileData = yield response.text().catch((error) => {
|
|
5031
|
-
console.error(`Failed to parse text from ${url}:`, error);
|
|
5032
|
-
});
|
|
5033
|
-
if (!fileData) {
|
|
5034
|
-
console.error(`No file data from ${url}`);
|
|
4984
|
+
const logger$8 = debug('app:react:item');
|
|
4985
|
+
const useItem = ({ modelName, seedLocalId, seedUid }) => {
|
|
4986
|
+
const [item, setItem] = useImmer(undefined);
|
|
4987
|
+
const [itemSubscription, setItemSubscription] = useState();
|
|
4988
|
+
const { status, internalStatus } = useGlobalServiceStatus();
|
|
4989
|
+
const isReadingDb = useRef(false);
|
|
4990
|
+
const itemStatus = useSelector(item === null || item === void 0 ? void 0 : item.getService(), (snapshot) => snapshot === null || snapshot === void 0 ? void 0 : snapshot.value);
|
|
4991
|
+
const updateItem = useCallback((newItem) => {
|
|
4992
|
+
setItem(() => newItem);
|
|
4993
|
+
}, []);
|
|
4994
|
+
const readFromDb = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
4995
|
+
if (isReadingDb.current ||
|
|
4996
|
+
internalStatus !== 'ready' ||
|
|
4997
|
+
(!seedUid && !seedLocalId)) {
|
|
5035
4998
|
return;
|
|
5036
4999
|
}
|
|
5037
|
-
|
|
5038
|
-
|
|
5000
|
+
isReadingDb.current = true;
|
|
5001
|
+
const foundItem = yield Item.find({
|
|
5002
|
+
modelName,
|
|
5003
|
+
seedLocalId,
|
|
5004
|
+
seedUid,
|
|
5005
|
+
});
|
|
5006
|
+
if (!foundItem) {
|
|
5007
|
+
logger$8('[useItem] [getItemFromDb] no item found', modelName, seedLocalId);
|
|
5039
5008
|
return;
|
|
5040
5009
|
}
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
if (match && match.length > 1) {
|
|
5048
|
-
migrationNumber = match[1];
|
|
5010
|
+
updateItem(foundItem);
|
|
5011
|
+
isReadingDb.current = false;
|
|
5012
|
+
}), [internalStatus]);
|
|
5013
|
+
useEffect(() => {
|
|
5014
|
+
if (internalStatus === 'ready') {
|
|
5015
|
+
readFromDb();
|
|
5049
5016
|
}
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
if (innerMatch && innerMatch.length > 1) {
|
|
5059
|
-
existingFileMigrationNumber = innerMatch[1];
|
|
5060
|
-
}
|
|
5061
|
-
if (migrationNumber &&
|
|
5062
|
-
existingFileMigrationNumber &&
|
|
5063
|
-
existingFileMigrationNumber === migrationNumber) {
|
|
5064
|
-
yield fs.promises.unlink(path.join(localDirPath, file));
|
|
5017
|
+
}, [internalStatus, status]);
|
|
5018
|
+
useEffect(() => {
|
|
5019
|
+
if (item && !itemSubscription) {
|
|
5020
|
+
const subscription = item.subscribe((_) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5021
|
+
const newItem = yield Item.find({ modelName, seedLocalId, seedUid });
|
|
5022
|
+
if (!newItem) {
|
|
5023
|
+
logger$8('[useItem] [itemSubscription] no item found', modelName, seedLocalId);
|
|
5024
|
+
return;
|
|
5065
5025
|
}
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
// const exists = await fs.promises.exists(localFilePath)
|
|
5070
|
-
// if (exists) {
|
|
5071
|
-
// await fs.promises.rm(localFilePath)
|
|
5072
|
-
// }
|
|
5073
|
-
// await fs.promises.writeFile(localFilePath, fileData)
|
|
5074
|
-
// }
|
|
5075
|
-
//
|
|
5076
|
-
// if (filename !== '_journal.json') {
|
|
5077
|
-
// await fs.promises.writeFile(localFilePath, fileData)
|
|
5078
|
-
// }
|
|
5079
|
-
yield fs.promises.writeFile(localFilePath, fileData);
|
|
5080
|
-
}
|
|
5081
|
-
catch (error) {
|
|
5082
|
-
if (JSON.stringify(error).includes('File exists')) {
|
|
5083
|
-
yield fs.promises.readFile(localFilePath, 'utf-8');
|
|
5026
|
+
setItem(() => newItem);
|
|
5027
|
+
}));
|
|
5028
|
+
setItemSubscription(subscription);
|
|
5084
5029
|
}
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
});
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5030
|
+
return () => {
|
|
5031
|
+
itemSubscription === null || itemSubscription === void 0 ? void 0 : itemSubscription.unsubscribe();
|
|
5032
|
+
};
|
|
5033
|
+
}, [item, itemSubscription]);
|
|
5034
|
+
useEffect(() => {
|
|
5035
|
+
const seedId = seedUid || seedLocalId;
|
|
5036
|
+
eventEmitter.addListener(`item.${modelName}.${seedId}.update`, readFromDb);
|
|
5037
|
+
return () => {
|
|
5038
|
+
eventEmitter.removeListener(`item.${modelName}.${seedId}.update`, readFromDb);
|
|
5039
|
+
};
|
|
5040
|
+
}, []);
|
|
5041
|
+
return {
|
|
5042
|
+
item,
|
|
5043
|
+
itemStatus,
|
|
5044
|
+
};
|
|
5045
|
+
};
|
|
5046
|
+
const useItems = ({ modelName, options }) => {
|
|
5047
|
+
const [items, setItems] = useImmer([]);
|
|
5048
|
+
const [isReadingDb, setIsReadingDb] = useState(false);
|
|
5049
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
5050
|
+
const { dbsAreReady } = useDbsAreReady();
|
|
5051
|
+
const modelNameRef = useRef(modelName);
|
|
5052
|
+
const readFromDb = useCallback((event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5053
|
+
if (!event ||
|
|
5054
|
+
!event.modelName ||
|
|
5055
|
+
event.modelName !== modelNameRef.current ||
|
|
5056
|
+
isReadingDb) {
|
|
5057
|
+
return;
|
|
5101
5058
|
}
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
});
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
}
|
|
5113
|
-
if (!everythingDownloaded) {
|
|
5114
|
-
setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
5115
|
-
yield confirmFilesExist(filePaths);
|
|
5116
|
-
}), 500);
|
|
5117
|
-
}
|
|
5118
|
-
});
|
|
5119
|
-
const syncDbFiles = (_a) => __awaiter(void 0, [_a], void 0, function* ({ filePaths, files }) {
|
|
5120
|
-
const fileList = yield fetchDirectory(filePaths);
|
|
5121
|
-
yield fetchFilesRecursively(files, BROWSER_FS_TOP_DIR, fileList);
|
|
5122
|
-
yield confirmFilesExist(fileList);
|
|
5123
|
-
logger$6('[syncDbFiles] Files synced!');
|
|
5124
|
-
});
|
|
5125
|
-
|
|
5126
|
-
const logger$5 = debug('app:files:download');
|
|
5127
|
-
const downloadAllFilesRequestHandler = (_a) => __awaiter(void 0, [_a], void 0, function* ({ endpoints, eventId, }) {
|
|
5128
|
-
yield syncDbFiles(endpoints);
|
|
5129
|
-
eventEmitter.emit('fs.downloadAll.success', { eventId });
|
|
5130
|
-
eventEmitter.emit('fs.downloadAllBinary.request', { endpoints });
|
|
5131
|
-
});
|
|
5132
|
-
const downloadAllFilesBinaryRequestHandler = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5133
|
-
const addresses = yield getAddressesFromDb();
|
|
5134
|
-
const { filesMetadata } = yield queryClient.fetchQuery({
|
|
5135
|
-
queryKey: ['getFilesMetadata', ...addresses],
|
|
5136
|
-
queryFn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5137
|
-
return easClient.request(GET_FILES_METADATA, {
|
|
5138
|
-
where: {
|
|
5139
|
-
attester: {
|
|
5140
|
-
in: addresses,
|
|
5141
|
-
},
|
|
5142
|
-
schema: {
|
|
5143
|
-
is: {
|
|
5144
|
-
id: {
|
|
5145
|
-
equals: '0x55fdefb36fcbbaebeb7d6b41dc3a1a9666e4e42154267c889de064faa7ede517',
|
|
5146
|
-
},
|
|
5147
|
-
},
|
|
5148
|
-
},
|
|
5149
|
-
},
|
|
5150
|
-
});
|
|
5151
|
-
}),
|
|
5152
|
-
});
|
|
5153
|
-
if (!(yield fs.promises.exists('/files'))) {
|
|
5154
|
-
yield fs.promises.mkdir('/files', { recursive: true });
|
|
5155
|
-
}
|
|
5156
|
-
if (!(yield fs.promises.exists('/files/html'))) {
|
|
5157
|
-
yield fs.promises.mkdir('/files/html', { recursive: true });
|
|
5158
|
-
}
|
|
5159
|
-
if (!(yield fs.promises.exists('/files/json'))) {
|
|
5160
|
-
yield fs.promises.mkdir('/files/json', { recursive: true });
|
|
5161
|
-
}
|
|
5162
|
-
if (!(yield fs.promises.exists('/files/images'))) {
|
|
5163
|
-
yield fs.promises.mkdir('/files/images', { recursive: true });
|
|
5164
|
-
}
|
|
5165
|
-
const seedDb = getDb(DB_NAME_SEED);
|
|
5166
|
-
if (!seedDb) {
|
|
5167
|
-
console.warn('[fetchAll/actors] [fetchAllBinaryData] seedDb not available');
|
|
5168
|
-
return [];
|
|
5169
|
-
}
|
|
5170
|
-
for (const fileMetadata of filesMetadata) {
|
|
5171
|
-
const json = JSON.parse(fileMetadata.decodedDataJson);
|
|
5172
|
-
const transactionId = json[0].value.value;
|
|
5173
|
-
const excludedTransactionsQuery = yield seedDb
|
|
5174
|
-
.select()
|
|
5175
|
-
.from(appState)
|
|
5176
|
-
.where(eq(appState.key, 'excludedTransactions'));
|
|
5177
|
-
let excludedTransactions = new Set();
|
|
5178
|
-
if (excludedTransactionsQuery && excludedTransactionsQuery.length === 1) {
|
|
5179
|
-
const valueString = excludedTransactionsQuery[0].value;
|
|
5180
|
-
if (valueString) {
|
|
5181
|
-
const excludedTransactionsArray = JSON.parse(valueString);
|
|
5182
|
-
excludedTransactions = new Set(excludedTransactionsArray);
|
|
5183
|
-
}
|
|
5184
|
-
}
|
|
5185
|
-
if (excludedTransactions.has(transactionId)) {
|
|
5186
|
-
continue;
|
|
5187
|
-
}
|
|
5188
|
-
const arweave = getArweave();
|
|
5189
|
-
if (!arweave) {
|
|
5190
|
-
console.warn('[fetchAll/actors] [fetchAllBinaryData] arweave not available');
|
|
5191
|
-
return [];
|
|
5192
|
-
}
|
|
5193
|
-
try {
|
|
5194
|
-
const res = yield fetch(`https://${ARWEAVE_HOST}/tx/${transactionId}/status`);
|
|
5195
|
-
if (res.status !== 200) {
|
|
5196
|
-
logger$5(`[fetchAll/actors] [fetchAllBinaryData] error fetching transaction data for ${transactionId}`);
|
|
5197
|
-
excludedTransactions.add(transactionId);
|
|
5198
|
-
yield writeAppState(seedDb, 'excludedTransactions', JSON.stringify(Array.from(excludedTransactions)));
|
|
5199
|
-
continue;
|
|
5200
|
-
}
|
|
5201
|
-
const dataString = yield arweave.transactions
|
|
5202
|
-
.getData(transactionId, {
|
|
5203
|
-
decode: true,
|
|
5204
|
-
string: true,
|
|
5205
|
-
})
|
|
5206
|
-
.catch((error) => {
|
|
5207
|
-
console.error(`[fetchAll/actors] [fetchAllBinaryData] error fetching transaction data for ${transactionId}`, error);
|
|
5208
|
-
});
|
|
5209
|
-
if (!dataString) {
|
|
5210
|
-
logger$5(`[fetchAll/actors] [fetchAllBinaryData] transaction ${transactionId} data not found`);
|
|
5211
|
-
}
|
|
5212
|
-
let contentType = identifyString(dataString);
|
|
5213
|
-
if (contentType !== 'json' &&
|
|
5214
|
-
contentType !== 'base64' &&
|
|
5215
|
-
contentType !== 'html') {
|
|
5216
|
-
const possibleImageType = getImageDataType(dataString);
|
|
5217
|
-
if (!possibleImageType) {
|
|
5218
|
-
logger$5(`[fetchAll/actors] [fetchAllBinaryData] transaction ${transactionId} data not in expected format: ${possibleImageType}`);
|
|
5219
|
-
continue;
|
|
5220
|
-
}
|
|
5221
|
-
contentType = possibleImageType;
|
|
5222
|
-
}
|
|
5223
|
-
if (contentType === 'url') {
|
|
5224
|
-
const url = dataString;
|
|
5225
|
-
const response = yield fetch(url);
|
|
5226
|
-
if (!response.ok) {
|
|
5227
|
-
throw new Error(`Failed to fetch image: ${response.statusText}`);
|
|
5228
|
-
}
|
|
5229
|
-
// Get the image as a Blob
|
|
5230
|
-
const blob = yield response.blob();
|
|
5231
|
-
const buffer = yield blob.arrayBuffer();
|
|
5232
|
-
const bufferUint8Array = new Uint8Array(buffer);
|
|
5233
|
-
// Extract the file extension from the URL
|
|
5234
|
-
const extensionMatch = url.match(/\.(jpg|jpeg|png|gif|bmp|webp|svg)$/i);
|
|
5235
|
-
if (!extensionMatch) {
|
|
5236
|
-
throw new Error('Unable to determine the file extension from the URL.');
|
|
5237
|
-
}
|
|
5238
|
-
const fileExtension = extensionMatch[0]; // e.g., ".jpg"
|
|
5239
|
-
// Set the file name (you can customize this)
|
|
5240
|
-
// const fileNameFromUrl = `${transactionId}${fileExtension}`
|
|
5241
|
-
yield fs.promises.writeFile(`/files/images/${transactionId}`, bufferUint8Array, {
|
|
5242
|
-
encoding: 'binary',
|
|
5243
|
-
});
|
|
5244
|
-
continue;
|
|
5245
|
-
}
|
|
5246
|
-
const mimeType = getMimeType(dataString);
|
|
5247
|
-
let fileName = transactionId;
|
|
5248
|
-
if (contentType === 'base64') {
|
|
5249
|
-
if (mimeType) {
|
|
5250
|
-
fileName += `.${mimeType}`;
|
|
5251
|
-
}
|
|
5252
|
-
// Remove the Base64 header if it exists (e.g., "data:image/png;base64,")
|
|
5253
|
-
const base64Data = dataString.split(',').pop() || '';
|
|
5254
|
-
// Decode the Base64 string to binary
|
|
5255
|
-
const binaryString = atob(base64Data);
|
|
5256
|
-
const length = binaryString.length;
|
|
5257
|
-
const binaryData = new Uint8Array(length);
|
|
5258
|
-
for (let i = 0; i < length; i++) {
|
|
5259
|
-
binaryData[i] = binaryString.charCodeAt(i);
|
|
5260
|
-
}
|
|
5261
|
-
yield fs.promises.writeFile(`/files/images/${fileName}`, binaryData, {
|
|
5262
|
-
encoding: 'binary',
|
|
5263
|
-
});
|
|
5264
|
-
// if (dataUint8Array && dataUint8Array instanceof Uint8Array) {
|
|
5265
|
-
// await fs.promises.writeFile(
|
|
5266
|
-
// `/files/images/${fileName}`,
|
|
5267
|
-
// dataUint8Array,
|
|
5268
|
-
// )
|
|
5269
|
-
// }
|
|
5270
|
-
}
|
|
5271
|
-
if (contentType === 'html') {
|
|
5272
|
-
fileName += '.html';
|
|
5273
|
-
yield fs.promises.writeFile(`/files/html/${fileName}`, dataString);
|
|
5274
|
-
}
|
|
5275
|
-
if (contentType === 'json') {
|
|
5276
|
-
fileName += '.json';
|
|
5277
|
-
yield fs.promises.writeFile(`/files/json/${fileName}`, dataString);
|
|
5278
|
-
}
|
|
5279
|
-
}
|
|
5280
|
-
catch (error) {
|
|
5281
|
-
logger$5(error);
|
|
5282
|
-
}
|
|
5283
|
-
}
|
|
5284
|
-
});
|
|
5285
|
-
|
|
5286
|
-
let isInitialized = false;
|
|
5287
|
-
const fsInitHandler = (_) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5288
|
-
if (isInitialized) {
|
|
5289
|
-
eventEmitter.emit('fs.init.response', { success: true });
|
|
5290
|
-
return;
|
|
5291
|
-
}
|
|
5292
|
-
try {
|
|
5293
|
-
const handle = yield navigator.storage.getDirectory();
|
|
5294
|
-
// await configure({ backend: WebAccess, handle })
|
|
5295
|
-
yield configureSingle({
|
|
5296
|
-
backend: WebAccess,
|
|
5297
|
-
handle,
|
|
5298
|
-
});
|
|
5299
|
-
isInitialized = true;
|
|
5300
|
-
eventEmitter.emit('fs.init.response', { success: true });
|
|
5301
|
-
}
|
|
5302
|
-
catch (e) {
|
|
5303
|
-
if (!isInitialized) {
|
|
5304
|
-
console.error('[fs.init] error initializing fs', e);
|
|
5305
|
-
eventEmitter.emit('fs.init.response', {
|
|
5306
|
-
success: false,
|
|
5307
|
-
error: e,
|
|
5059
|
+
setIsReadingDb(true);
|
|
5060
|
+
const allItems = yield Item.all(modelNameRef.current);
|
|
5061
|
+
setItems(() => allItems);
|
|
5062
|
+
setIsReadingDb(false);
|
|
5063
|
+
}), [modelName]);
|
|
5064
|
+
useEffect(() => {
|
|
5065
|
+
if (dbsAreReady && !isInitialized) {
|
|
5066
|
+
const _fetchItems = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5067
|
+
yield readFromDb({ modelName });
|
|
5068
|
+
setIsInitialized(true);
|
|
5308
5069
|
});
|
|
5070
|
+
_fetchItems();
|
|
5309
5071
|
}
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5072
|
+
}, [dbsAreReady, isInitialized]);
|
|
5073
|
+
useEffect(() => {
|
|
5074
|
+
eventEmitter.addListener('item.requestAll', readFromDb);
|
|
5075
|
+
return () => {
|
|
5076
|
+
eventEmitter.removeListener('item.requestAll');
|
|
5077
|
+
};
|
|
5078
|
+
}, []);
|
|
5079
|
+
return {
|
|
5080
|
+
items: orderBy(items, [
|
|
5081
|
+
(item) => item.lastVersionPublishedAt ||
|
|
5082
|
+
item.attestationCreatedAt ||
|
|
5083
|
+
item.createdAt,
|
|
5084
|
+
], ['desc']).slice(0, 10),
|
|
5085
|
+
isReadingDb,
|
|
5086
|
+
isInitialized,
|
|
5087
|
+
};
|
|
5325
5088
|
};
|
|
5326
|
-
|
|
5327
|
-
const
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
if (!endpoints || !endpoints.filePaths || !endpoints.files) {
|
|
5336
|
-
throw new Error('validateInput called with invalid endpoints');
|
|
5337
|
-
}
|
|
5338
|
-
if (!addresses || !addresses.length) {
|
|
5339
|
-
throw new Error('validateInput called with invalid addresses');
|
|
5340
|
-
}
|
|
5341
|
-
const _validateInput = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5342
|
-
sendBack({
|
|
5343
|
-
type: INTERNAL_VALIDATING_INPUT_SUCCESS,
|
|
5344
|
-
endpoints,
|
|
5345
|
-
addresses,
|
|
5346
|
-
});
|
|
5347
|
-
});
|
|
5348
|
-
_validateInput().then(() => {
|
|
5349
|
-
return;
|
|
5350
|
-
});
|
|
5351
|
-
});
|
|
5352
|
-
const prepareDb = fromCallback(({ sendBack, input: { event, context } }) => {
|
|
5353
|
-
const _prepareDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5354
|
-
if (typeof window === 'undefined') {
|
|
5355
|
-
return;
|
|
5089
|
+
const useItemIsReady = () => {
|
|
5090
|
+
const [itemListenersReady, setItemListenersReady] = useState(false);
|
|
5091
|
+
const itemEventListenersHandler = useCallback((_) => {
|
|
5092
|
+
setItemListenersReady(true);
|
|
5093
|
+
}, []);
|
|
5094
|
+
useEffect(() => {
|
|
5095
|
+
const areReady = getAreItemEventHandlersReady();
|
|
5096
|
+
if (areReady) {
|
|
5097
|
+
itemEventListenersHandler(true);
|
|
5356
5098
|
}
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5099
|
+
eventEmitter.addListener('item.events.setupAllItemsEventHandlers', itemEventListenersHandler);
|
|
5100
|
+
return () => {
|
|
5101
|
+
eventEmitter.removeListener('item.events.setupAllItemsEventHandlers');
|
|
5102
|
+
};
|
|
5103
|
+
}, []);
|
|
5104
|
+
return {
|
|
5105
|
+
isReady: itemListenersReady,
|
|
5106
|
+
};
|
|
5107
|
+
};
|
|
5108
|
+
const useCreateItem = (modelName) => {
|
|
5109
|
+
const [isCreatingItem, setIsCreatingItem] = useState(false);
|
|
5110
|
+
const { isReady } = useItemIsReady();
|
|
5111
|
+
const createItem = useCallback((itemData) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5112
|
+
if (!isReady) {
|
|
5113
|
+
console.error(`[useCreateItem] [createItem] called before listeners are ready`, itemData);
|
|
5366
5114
|
return;
|
|
5367
5115
|
}
|
|
5368
|
-
|
|
5116
|
+
if (isCreatingItem) {
|
|
5117
|
+
// TODO: should we setup a queue for this?
|
|
5118
|
+
console.error(`[useCreateItem] [createItem] already creating item`, itemData);
|
|
5369
5119
|
return;
|
|
5370
|
-
});
|
|
5371
|
-
}, 500);
|
|
5372
|
-
return () => {
|
|
5373
|
-
if (interval) {
|
|
5374
|
-
clearInterval(interval);
|
|
5375
5120
|
}
|
|
5121
|
+
setIsCreatingItem(true);
|
|
5122
|
+
const { seedLocalId } = yield createNewItem(Object.assign({ modelName }, itemData));
|
|
5123
|
+
yield Item.find({ modelName, seedLocalId });
|
|
5124
|
+
eventEmitter.emit('item.requestAll', { modelName });
|
|
5125
|
+
setIsCreatingItem(false);
|
|
5126
|
+
}), [isCreatingItem, isReady]);
|
|
5127
|
+
return {
|
|
5128
|
+
createItem,
|
|
5129
|
+
isCreatingItem,
|
|
5376
5130
|
};
|
|
5377
|
-
}
|
|
5378
|
-
const
|
|
5379
|
-
const
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
logger$4('[internal/actors] [configureFs] calling _configureFs');
|
|
5384
|
-
logger$4('[internal/actors] [configureFs] areFsListenersReady:', areFsListenersReady());
|
|
5385
|
-
logger$4('[internal/actors] [configureFs] isFsInitialized:', isFsInitialized());
|
|
5386
|
-
yield waitForEvent({
|
|
5387
|
-
req: {
|
|
5388
|
-
eventLabel: 'fs.downloadAll.request',
|
|
5389
|
-
data: { endpoints },
|
|
5390
|
-
},
|
|
5391
|
-
res: {
|
|
5392
|
-
eventLabel: 'fs.downloadAll.success',
|
|
5393
|
-
},
|
|
5394
|
-
});
|
|
5395
|
-
yield Promise.all(services.map((service) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5396
|
-
const { dirName } = service.getSnapshot().context;
|
|
5397
|
-
const journalPath = `${BROWSER_FS_TOP_DIR}/${dirName}/db/meta/_journal.json`;
|
|
5398
|
-
const journalExists = yield fs.promises.exists(journalPath);
|
|
5399
|
-
if (journalExists) {
|
|
5400
|
-
service.send({ type: DB_WAITING_FOR_FILES_RECEIVED });
|
|
5401
|
-
}
|
|
5402
|
-
// return new Promise<void>((resolve) => {
|
|
5403
|
-
// const interval = setInterval(() => {
|
|
5404
|
-
// journalExistsSync = fs.existsSync(journalPath)
|
|
5405
|
-
// logger(
|
|
5406
|
-
// '[internal/actors] [configureFs] journalExistsSync:',
|
|
5407
|
-
// journalExistsSync,
|
|
5408
|
-
// )
|
|
5409
|
-
// if (journalExistsSync) {
|
|
5410
|
-
// service.send({ type: DB_WAITING_FOR_FILES_RECEIVED })
|
|
5411
|
-
// clearInterval(interval)
|
|
5412
|
-
// resolve()
|
|
5413
|
-
// }
|
|
5414
|
-
// }, 200)
|
|
5415
|
-
// })
|
|
5416
|
-
})));
|
|
5417
|
-
logger$4('[internal/actors] [configureFs] fs configured!');
|
|
5418
|
-
});
|
|
5419
|
-
// Some of our dependencies use fs sync functions, which don't work with
|
|
5420
|
-
// OPFS. ZenFS creates an async cache of all files so that the sync functions
|
|
5421
|
-
// work, but we have to wait for it to be built. Otherwise things like
|
|
5422
|
-
// drizzleMigrate will fail since they can't see the migration files yet.
|
|
5423
|
-
_configureFs().then(() => {
|
|
5424
|
-
sendBack({ type: INTERNAL_CONFIGURING_FS_SUCCESS });
|
|
5425
|
-
return;
|
|
5426
|
-
});
|
|
5427
|
-
return () => { };
|
|
5428
|
-
});
|
|
5429
|
-
const loadSeedDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
5430
|
-
const { seedDbService } = context;
|
|
5431
|
-
if (seedDbService.getSnapshot().value === 'ready') {
|
|
5432
|
-
sendBack({ type: INTERNAL_LOADING_SEED_DB_SUCCESS });
|
|
5433
|
-
return () => { };
|
|
5434
|
-
}
|
|
5435
|
-
let subscription;
|
|
5436
|
-
const _loadSeedDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5437
|
-
yield waitFor(seedDbService, (snapshot) => snapshot.value === 'ready');
|
|
5438
|
-
subscription = seedDbService.subscribe({
|
|
5439
|
-
next: (snapshot) => {
|
|
5440
|
-
sendBack({ type: DB_ON_SNAPSHOT, dbName: DB_NAME_SEED, snapshot });
|
|
5441
|
-
},
|
|
5442
|
-
});
|
|
5443
|
-
});
|
|
5444
|
-
_loadSeedDb().then(() => {
|
|
5445
|
-
sendBack({ type: INTERNAL_LOADING_SEED_DB_SUCCESS });
|
|
5446
|
-
});
|
|
5447
|
-
return () => {
|
|
5448
|
-
if (subscription) {
|
|
5449
|
-
subscription.unsubscribe();
|
|
5131
|
+
};
|
|
5132
|
+
const useDeleteItem = () => {
|
|
5133
|
+
const [isDeletingItem, setIsDeletingItem] = useState(false);
|
|
5134
|
+
const destroy = useCallback((item) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5135
|
+
if (!item) {
|
|
5136
|
+
return;
|
|
5450
5137
|
}
|
|
5138
|
+
setIsDeletingItem(true);
|
|
5139
|
+
const { modelName } = item.getService().getSnapshot().context;
|
|
5140
|
+
yield deleteItem({ seedLocalId: item.seedLocalId });
|
|
5141
|
+
eventEmitter.emit('item.requestAll', { modelName });
|
|
5142
|
+
setIsDeletingItem(false);
|
|
5143
|
+
}), [isDeletingItem]);
|
|
5144
|
+
useEffect(() => { }, []);
|
|
5145
|
+
return {
|
|
5146
|
+
deleteItem: destroy,
|
|
5147
|
+
isDeletingItem,
|
|
5451
5148
|
};
|
|
5452
|
-
}
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
throw new Error('saveConfig called with invalid endpoints');
|
|
5464
|
-
}
|
|
5465
|
-
const _saveConfig = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5466
|
-
// logger('[sdk] [internal/actors] starting _saveConfig')
|
|
5467
|
-
const seedDb = getDb(DB_NAME_SEED);
|
|
5468
|
-
if (!seedDb) {
|
|
5469
|
-
throw new Error('Seed DB not found');
|
|
5149
|
+
};
|
|
5150
|
+
|
|
5151
|
+
const logger$7 = debug('app:react:property');
|
|
5152
|
+
const useItemProperty = (propertyName, seedLocalId) => {
|
|
5153
|
+
const [property, setProperty] = useImmer(undefined);
|
|
5154
|
+
const [isReadingFromDb, setIsReadingFromDb] = useState(false);
|
|
5155
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
5156
|
+
const dbsAreReady = useDbsAreReady();
|
|
5157
|
+
const value = useSelector(property === null || property === void 0 ? void 0 : property.getService(), (snapshot) => {
|
|
5158
|
+
if (!snapshot || !snapshot.context) {
|
|
5159
|
+
return;
|
|
5470
5160
|
}
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
.insert(appState)
|
|
5478
|
-
.values({
|
|
5479
|
-
key: 'endpoints',
|
|
5480
|
-
value: endpointsValueString,
|
|
5481
|
-
})
|
|
5482
|
-
.onConflictDoUpdate({
|
|
5483
|
-
target: appState.key,
|
|
5484
|
-
set: {
|
|
5485
|
-
value: endpointsValueString,
|
|
5486
|
-
},
|
|
5487
|
-
setWhere: sql `key = 'endpoints'`,
|
|
5488
|
-
});
|
|
5489
|
-
// logger('[sdk] [internal/actors] Saving addresses to db')
|
|
5490
|
-
yield seedDb
|
|
5491
|
-
.insert(appState)
|
|
5492
|
-
.values({
|
|
5493
|
-
key: 'addresses',
|
|
5494
|
-
value: addressesValueString,
|
|
5495
|
-
})
|
|
5496
|
-
.onConflictDoUpdate({
|
|
5497
|
-
target: appState.key,
|
|
5498
|
-
set: {
|
|
5499
|
-
value: addressesValueString,
|
|
5500
|
-
},
|
|
5501
|
-
setWhere: sql `key = 'addresses'`,
|
|
5502
|
-
});
|
|
5503
|
-
logger$4('[sdk] [internal/actors] Should be done saving');
|
|
5161
|
+
return snapshot.context.renderValue || snapshot.context.propertyValue;
|
|
5162
|
+
});
|
|
5163
|
+
const status = useSelector(property === null || property === void 0 ? void 0 : property.getService(), (snapshot) => snapshot === null || snapshot === void 0 ? void 0 : snapshot.value);
|
|
5164
|
+
useEffect(() => {
|
|
5165
|
+
if (dbsAreReady && property && property.value !== value) {
|
|
5166
|
+
readFromDb();
|
|
5504
5167
|
}
|
|
5505
|
-
|
|
5506
|
-
|
|
5168
|
+
}, [dbsAreReady, property, value]);
|
|
5169
|
+
const readFromDb = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
5170
|
+
if (!dbsAreReady && isReadingFromDb) {
|
|
5171
|
+
return;
|
|
5507
5172
|
}
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
});
|
|
5515
|
-
const loadAppDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
5516
|
-
const { appDbService } = context;
|
|
5517
|
-
let subscription;
|
|
5518
|
-
const _loadAppDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5519
|
-
return new Promise((resolve) => {
|
|
5520
|
-
if (appDbService.getSnapshot().value === 'ready') {
|
|
5521
|
-
return resolve();
|
|
5522
|
-
}
|
|
5523
|
-
subscription = appDbService.subscribe({
|
|
5524
|
-
next: (snapshot) => {
|
|
5525
|
-
if (snapshot.value === 'ready') {
|
|
5526
|
-
return resolve();
|
|
5527
|
-
}
|
|
5528
|
-
sendBack({ type: DB_ON_SNAPSHOT, dbName: DB_NAME_APP, snapshot });
|
|
5529
|
-
},
|
|
5530
|
-
});
|
|
5531
|
-
});
|
|
5532
|
-
});
|
|
5533
|
-
_loadAppDb().then(() => {
|
|
5534
|
-
sendBack({ type: INTERNAL_LOADING_APP_DB_SUCCESS });
|
|
5535
|
-
logger$4('[sdk] [internal/actors] Successfully loaded app DB');
|
|
5536
|
-
});
|
|
5537
|
-
return () => {
|
|
5538
|
-
if (subscription) {
|
|
5539
|
-
subscription.unsubscribe();
|
|
5173
|
+
setIsReadingFromDb(true);
|
|
5174
|
+
const foundProperty = yield ItemProperty.find({ propertyName, seedLocalId });
|
|
5175
|
+
setIsReadingFromDb(false);
|
|
5176
|
+
if (!foundProperty) {
|
|
5177
|
+
logger$7(`[useItemPropertyTest] [readFromDb] no property found for Item.${seedLocalId}.${propertyName}`);
|
|
5178
|
+
return;
|
|
5540
5179
|
}
|
|
5180
|
+
setProperty(() => foundProperty);
|
|
5181
|
+
setIsInitialized(true);
|
|
5182
|
+
}), [dbsAreReady, isReadingFromDb]);
|
|
5183
|
+
useEffect(() => {
|
|
5184
|
+
readFromDb();
|
|
5185
|
+
}, []);
|
|
5186
|
+
// TODO: How can we force a re-render when the property is updated?
|
|
5187
|
+
// Right now, the value will trigger an update because it's using a selector
|
|
5188
|
+
// and a change is pushed to the hook listener.
|
|
5189
|
+
return {
|
|
5190
|
+
property,
|
|
5191
|
+
isInitialized,
|
|
5192
|
+
isReadingFromDb,
|
|
5193
|
+
value,
|
|
5194
|
+
status,
|
|
5541
5195
|
};
|
|
5542
|
-
}
|
|
5543
|
-
const
|
|
5544
|
-
const
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
sendBack({
|
|
5558
|
-
type: DB_ON_SNAPSHOT,
|
|
5559
|
-
dbName: DB_NAME_SDK_CONFIG,
|
|
5560
|
-
snapshot,
|
|
5561
|
-
});
|
|
5562
|
-
},
|
|
5563
|
-
});
|
|
5196
|
+
};
|
|
5197
|
+
const useItemProperties = (item) => {
|
|
5198
|
+
const [propertyObj, setPropertyObj] = useImmer({});
|
|
5199
|
+
useState(false);
|
|
5200
|
+
const updatePropertyObj = useCallback((event) => {
|
|
5201
|
+
if (!item) {
|
|
5202
|
+
console.error('[XXXXXX] [updatePropertyObj] no item when expected');
|
|
5203
|
+
return;
|
|
5204
|
+
}
|
|
5205
|
+
const { propertyName, propertyValue } = event;
|
|
5206
|
+
if (!propertyName) {
|
|
5207
|
+
return;
|
|
5208
|
+
}
|
|
5209
|
+
setPropertyObj((draft) => {
|
|
5210
|
+
draft[propertyName] = propertyValue;
|
|
5564
5211
|
});
|
|
5565
|
-
});
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
});
|
|
5570
|
-
return () => {
|
|
5571
|
-
if (subscription) {
|
|
5572
|
-
subscription.unsubscribe();
|
|
5212
|
+
}, [item]);
|
|
5213
|
+
useEffect(() => {
|
|
5214
|
+
if (!item) {
|
|
5215
|
+
return;
|
|
5573
5216
|
}
|
|
5217
|
+
const eventKey = `item.${item.seedLocalId}.property.update`;
|
|
5218
|
+
eventEmitter.addListener(eventKey, updatePropertyObj);
|
|
5219
|
+
return () => {
|
|
5220
|
+
eventEmitter.removeListener(eventKey, updatePropertyObj);
|
|
5221
|
+
};
|
|
5222
|
+
}, [item]);
|
|
5223
|
+
return {
|
|
5224
|
+
properties: propertyObj,
|
|
5574
5225
|
};
|
|
5575
|
-
}
|
|
5226
|
+
};
|
|
5576
5227
|
|
|
5577
|
-
const logger$
|
|
5228
|
+
const logger$6 = debug('app:global:actors');
|
|
5229
|
+
const initialize = fromCallback(({ sendBack, input: { event, context } }) => {
|
|
5230
|
+
const { internalService, models, endpoints } = context;
|
|
5231
|
+
const { addresses } = event;
|
|
5232
|
+
let environment = 'browser';
|
|
5233
|
+
if (isNode()) {
|
|
5234
|
+
environment = 'node';
|
|
5235
|
+
}
|
|
5236
|
+
if (isReactNative()) {
|
|
5237
|
+
environment = 'react-native';
|
|
5238
|
+
}
|
|
5239
|
+
let internalSubscription;
|
|
5240
|
+
if (environment === 'browser' && models) {
|
|
5241
|
+
const _initFileSystem = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5242
|
+
return;
|
|
5243
|
+
// return new Promise((resolve) => {
|
|
5244
|
+
// })
|
|
5245
|
+
});
|
|
5246
|
+
const _initInternal = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5247
|
+
return new Promise((resolve) => {
|
|
5248
|
+
internalSubscription = internalService.subscribe((snapshot) => {
|
|
5249
|
+
logger$6('[sdk] [internal] snapshot', snapshot);
|
|
5250
|
+
if (snapshot.value === 'ready') {
|
|
5251
|
+
resolve();
|
|
5252
|
+
}
|
|
5253
|
+
});
|
|
5254
|
+
internalService.send({ type: 'init', endpoints, addresses });
|
|
5255
|
+
});
|
|
5256
|
+
});
|
|
5257
|
+
_initFileSystem().then(() => {
|
|
5258
|
+
logger$6('[global/actors] File system initialized');
|
|
5259
|
+
});
|
|
5260
|
+
_initInternal().then(() => {
|
|
5261
|
+
logger$6('[global/actors] Internal initialized');
|
|
5262
|
+
sendBack({ type: GLOBAL_INITIALIZING_INTERNAL_SERVICE_READY });
|
|
5263
|
+
internalSubscription === null || internalSubscription === void 0 ? void 0 : internalSubscription.unsubscribe();
|
|
5264
|
+
});
|
|
5265
|
+
// _initEas().then(() => {
|
|
5266
|
+
// logger('EAS initialized')
|
|
5267
|
+
// })
|
|
5268
|
+
}
|
|
5269
|
+
sendBack({ type: GLOBAL_INITIALIZING_SEND_CONFIG, environment });
|
|
5270
|
+
return () => {
|
|
5271
|
+
internalSubscription === null || internalSubscription === void 0 ? void 0 : internalSubscription.unsubscribe();
|
|
5272
|
+
};
|
|
5273
|
+
});
|
|
5274
|
+
const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
5275
|
+
const { models: models$1 } = context;
|
|
5276
|
+
const _addModelsToDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5277
|
+
var _a;
|
|
5278
|
+
const sdkConfigDb = getSdkDb();
|
|
5279
|
+
if (!models$1) {
|
|
5280
|
+
return;
|
|
5281
|
+
}
|
|
5282
|
+
const { models: SeedModels } = yield import('./seed.schema.config-t5AiIDm_.js');
|
|
5283
|
+
const allModels = Object.assign(Object.assign({}, SeedModels), models$1);
|
|
5284
|
+
let hasModelsInDb = false;
|
|
5285
|
+
const schemaDefsByModelName = new Map();
|
|
5286
|
+
for (const [modelName, _] of Object.entries(allModels)) {
|
|
5287
|
+
logger$6('[helpers/db] [addModelsToInternalDb] starting modelName:', modelName);
|
|
5288
|
+
let foundModel;
|
|
5289
|
+
const foundModelsQuery = yield sdkConfigDb
|
|
5290
|
+
.select()
|
|
5291
|
+
.from(models)
|
|
5292
|
+
.where(eq(models.name, modelName));
|
|
5293
|
+
if (!foundModelsQuery || foundModelsQuery.length === 0) {
|
|
5294
|
+
yield sdkConfigDb.insert(models).values({
|
|
5295
|
+
name: modelName,
|
|
5296
|
+
});
|
|
5297
|
+
logger$6('[global/actors] [addModelsToDb] inserted model:', modelName);
|
|
5298
|
+
const foundModels = yield sdkConfigDb
|
|
5299
|
+
.select({
|
|
5300
|
+
id: models.id,
|
|
5301
|
+
name: models.name,
|
|
5302
|
+
uid: modelUids.uid,
|
|
5303
|
+
})
|
|
5304
|
+
.from(models)
|
|
5305
|
+
.leftJoin(modelUids, eq(models.id, modelUids.modelId))
|
|
5306
|
+
.where(eq(models.name, modelName))
|
|
5307
|
+
.limit(1);
|
|
5308
|
+
foundModel = foundModels[0];
|
|
5309
|
+
}
|
|
5310
|
+
if (foundModelsQuery && foundModelsQuery.length > 0) {
|
|
5311
|
+
foundModel = foundModelsQuery[0];
|
|
5312
|
+
}
|
|
5313
|
+
if (!foundModel) {
|
|
5314
|
+
hasModelsInDb = false;
|
|
5315
|
+
break;
|
|
5316
|
+
}
|
|
5317
|
+
schemaDefsByModelName.set(modelName, {
|
|
5318
|
+
dbId: foundModel.id,
|
|
5319
|
+
schemaDef: `bytes32 ${toSnakeCase(modelName)}`,
|
|
5320
|
+
});
|
|
5321
|
+
}
|
|
5322
|
+
if (!hasModelsInDb) {
|
|
5323
|
+
return false;
|
|
5324
|
+
}
|
|
5325
|
+
const schemaDefs = Array.from(schemaDefsByModelName.values()).map(({ schemaDef }) => schemaDef);
|
|
5326
|
+
const { schemas } = yield queryClient.fetchQuery({
|
|
5327
|
+
queryKey: [`getSchemasVersion`],
|
|
5328
|
+
queryFn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5329
|
+
return easClient.request(GET_SCHEMAS, {
|
|
5330
|
+
where: {
|
|
5331
|
+
schema: {
|
|
5332
|
+
in: schemaDefs,
|
|
5333
|
+
},
|
|
5334
|
+
},
|
|
5335
|
+
});
|
|
5336
|
+
}),
|
|
5337
|
+
});
|
|
5338
|
+
if (!schemas || schemas.length === 0) {
|
|
5339
|
+
throw new Error(`No schemas found`);
|
|
5340
|
+
}
|
|
5341
|
+
for (const schema of schemas) {
|
|
5342
|
+
const modelId = (_a = Array.from(schemaDefsByModelName.values()).find(({ schemaDef }) => schemaDef === schema.schema)) === null || _a === void 0 ? void 0 : _a.dbId;
|
|
5343
|
+
if (!modelId) {
|
|
5344
|
+
throw new Error(`No modelId found for schema ${schema.schema}`);
|
|
5345
|
+
}
|
|
5346
|
+
yield sdkConfigDb
|
|
5347
|
+
.insert(modelUids)
|
|
5348
|
+
.values({
|
|
5349
|
+
modelId,
|
|
5350
|
+
uid: schema.id,
|
|
5351
|
+
})
|
|
5352
|
+
.onConflictDoNothing();
|
|
5353
|
+
}
|
|
5354
|
+
});
|
|
5355
|
+
_addModelsToDb().then((hasModelsInDb) => {
|
|
5356
|
+
sendBack({ type: GLOBAL_ADDING_MODELS_TO_DB_SUCCESS });
|
|
5357
|
+
for (const [modelName, model] of Object.entries(models$1)) {
|
|
5358
|
+
const service = context[`${modelName}Service`];
|
|
5359
|
+
service.send({ type: 'modelsFound' });
|
|
5360
|
+
}
|
|
5361
|
+
eventEmitter.emit('syncDbWithEas');
|
|
5362
|
+
return;
|
|
5363
|
+
});
|
|
5364
|
+
return () => { };
|
|
5365
|
+
});
|
|
5366
|
+
const getSchemaForModel = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
5367
|
+
const { modelName } = event;
|
|
5368
|
+
if (!modelName) {
|
|
5369
|
+
console.warn('No modelName found');
|
|
5370
|
+
return;
|
|
5371
|
+
}
|
|
5372
|
+
const { models } = context;
|
|
5373
|
+
if (!models) {
|
|
5374
|
+
console.warn('No models found');
|
|
5375
|
+
return;
|
|
5376
|
+
}
|
|
5377
|
+
const model = Object.entries(models).find(([modelNameFromConfig]) => modelNameFromConfig === modelName);
|
|
5378
|
+
if (!model) {
|
|
5379
|
+
throw new Error(`Model ${modelName} not found`);
|
|
5380
|
+
}
|
|
5381
|
+
logger$6('[service/actor] [getSchemaForModel] model:', model);
|
|
5382
|
+
sendBack({ type: 'schemaForModel', schema: model.schema });
|
|
5383
|
+
return () => { };
|
|
5384
|
+
});
|
|
5385
|
+
|
|
5386
|
+
class SqliteConnectionManager {
|
|
5387
|
+
constructor(sqliteModule, idleTimeout = 300000) {
|
|
5388
|
+
// Default idle timeout: 5 minutes
|
|
5389
|
+
this.sqliteModule = sqliteModule;
|
|
5390
|
+
this.idleTimeout = idleTimeout;
|
|
5391
|
+
this.databases = {};
|
|
5392
|
+
this.idleTimers = {};
|
|
5393
|
+
}
|
|
5394
|
+
resetIdleTimer(dbName) {
|
|
5395
|
+
if (this.idleTimers[dbName]) {
|
|
5396
|
+
clearTimeout(this.idleTimers[dbName]);
|
|
5397
|
+
}
|
|
5398
|
+
this.idleTimers[dbName] = setTimeout(() => {
|
|
5399
|
+
this.closeConnection(dbName);
|
|
5400
|
+
}, this.idleTimeout);
|
|
5401
|
+
}
|
|
5402
|
+
getConnection(dbName) {
|
|
5403
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
5404
|
+
if (this.databases[dbName]) {
|
|
5405
|
+
this.resetIdleTimer(dbName);
|
|
5406
|
+
return this.databases[dbName];
|
|
5407
|
+
}
|
|
5408
|
+
const db = new this.sqliteModule();
|
|
5409
|
+
yield db.open(dbName);
|
|
5410
|
+
this.databases[dbName] = db;
|
|
5411
|
+
this.resetIdleTimer(dbName);
|
|
5412
|
+
return db;
|
|
5413
|
+
});
|
|
5414
|
+
}
|
|
5415
|
+
execute(dbName_1, sql_1) {
|
|
5416
|
+
return __awaiter(this, arguments, void 0, function* (dbName, sql, params = []) {
|
|
5417
|
+
const db = yield this.getConnection(dbName);
|
|
5418
|
+
const result = db.exec(sql, params);
|
|
5419
|
+
this.resetIdleTimer(dbName);
|
|
5420
|
+
return result;
|
|
5421
|
+
});
|
|
5422
|
+
}
|
|
5423
|
+
closeConnection(dbName) {
|
|
5424
|
+
if (this.databases[dbName]) {
|
|
5425
|
+
this.databases[dbName].close();
|
|
5426
|
+
delete this.databases[dbName];
|
|
5427
|
+
if (this.idleTimers[dbName]) {
|
|
5428
|
+
clearTimeout(this.idleTimers[dbName]);
|
|
5429
|
+
delete this.idleTimers[dbName];
|
|
5430
|
+
}
|
|
5431
|
+
}
|
|
5432
|
+
}
|
|
5433
|
+
}
|
|
5434
|
+
|
|
5435
|
+
const logger$5 = debug('app:services:internal:helpers');
|
|
5436
|
+
/**
|
|
5437
|
+
* Recursively create directories if they don't exist.
|
|
5438
|
+
* @param {string} dirPath - The directory path to create.
|
|
5439
|
+
*/
|
|
5440
|
+
const createDirectories = (dirPath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5441
|
+
const dirPathExists = yield fs.promises.exists(dirPath);
|
|
5442
|
+
if (dirPathExists) {
|
|
5443
|
+
return;
|
|
5444
|
+
}
|
|
5445
|
+
const parentDir = path.dirname(dirPath);
|
|
5446
|
+
const parentDirExists = yield fs.promises.exists(parentDir);
|
|
5447
|
+
if (!parentDirExists) {
|
|
5448
|
+
yield createDirectories(parentDir);
|
|
5449
|
+
}
|
|
5450
|
+
yield fs.promises.mkdir(dirPath, { recursive: true });
|
|
5451
|
+
});
|
|
5452
|
+
let busy = false;
|
|
5453
|
+
const downloadFile = (url, localFilePath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5454
|
+
try {
|
|
5455
|
+
const response = yield fetch(url);
|
|
5456
|
+
const fileData = yield response.text().catch((error) => {
|
|
5457
|
+
console.error(`Failed to parse text from ${url}:`, error);
|
|
5458
|
+
});
|
|
5459
|
+
if (!fileData) {
|
|
5460
|
+
console.error(`No file data from ${url}`);
|
|
5461
|
+
return;
|
|
5462
|
+
}
|
|
5463
|
+
const localDirPath = path.dirname(localFilePath);
|
|
5464
|
+
if (busy) {
|
|
5465
|
+
return;
|
|
5466
|
+
}
|
|
5467
|
+
busy = true;
|
|
5468
|
+
yield createDirectories(localDirPath);
|
|
5469
|
+
const filename = path.basename(localFilePath);
|
|
5470
|
+
const regex = /(\d+)[\w_]+\.(sql|json)$/;
|
|
5471
|
+
const match = filename.match(regex);
|
|
5472
|
+
let migrationNumber;
|
|
5473
|
+
if (match && match.length > 1) {
|
|
5474
|
+
migrationNumber = match[1];
|
|
5475
|
+
}
|
|
5476
|
+
if (migrationNumber) {
|
|
5477
|
+
const filesInDir = yield fs.promises.readdir(localDirPath);
|
|
5478
|
+
for (const file of filesInDir) {
|
|
5479
|
+
if (file === filename) {
|
|
5480
|
+
continue;
|
|
5481
|
+
}
|
|
5482
|
+
const innerMatch = file.match(regex);
|
|
5483
|
+
let existingFileMigrationNumber;
|
|
5484
|
+
if (innerMatch && innerMatch.length > 1) {
|
|
5485
|
+
existingFileMigrationNumber = innerMatch[1];
|
|
5486
|
+
}
|
|
5487
|
+
if (migrationNumber &&
|
|
5488
|
+
existingFileMigrationNumber &&
|
|
5489
|
+
existingFileMigrationNumber === migrationNumber) {
|
|
5490
|
+
yield fs.promises.unlink(path.join(localDirPath, file));
|
|
5491
|
+
}
|
|
5492
|
+
}
|
|
5493
|
+
}
|
|
5494
|
+
// if (filename === '_journal.json') {
|
|
5495
|
+
// const exists = await fs.promises.exists(localFilePath)
|
|
5496
|
+
// if (exists) {
|
|
5497
|
+
// await fs.promises.rm(localFilePath)
|
|
5498
|
+
// }
|
|
5499
|
+
// await fs.promises.writeFile(localFilePath, fileData)
|
|
5500
|
+
// }
|
|
5501
|
+
//
|
|
5502
|
+
// if (filename !== '_journal.json') {
|
|
5503
|
+
// await fs.promises.writeFile(localFilePath, fileData)
|
|
5504
|
+
// }
|
|
5505
|
+
yield fs.promises.writeFile(localFilePath, fileData);
|
|
5506
|
+
}
|
|
5507
|
+
catch (error) {
|
|
5508
|
+
if (JSON.stringify(error).includes('File exists')) {
|
|
5509
|
+
yield fs.promises.readFile(localFilePath, 'utf-8');
|
|
5510
|
+
}
|
|
5511
|
+
logger$5(`[Error] Failed to download file from ${url}:`, error);
|
|
5512
|
+
}
|
|
5513
|
+
busy = false;
|
|
5514
|
+
});
|
|
5515
|
+
const fetchDirectory = (url) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5516
|
+
const response = yield fetch(url);
|
|
5517
|
+
return response.json();
|
|
5518
|
+
});
|
|
5519
|
+
const fetchFilesRecursively = (url, localPath, fileList) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5520
|
+
try {
|
|
5521
|
+
for (const file of fileList) {
|
|
5522
|
+
const fileUrl = `${url}/${file}`;
|
|
5523
|
+
const fileLocalPath = path.join(localPath, file);
|
|
5524
|
+
// logger(`[fetchFilesRecursively] fileUrl: ${fileUrl}`)
|
|
5525
|
+
// logger(`[fetchFilesRecursively] fileLocalPath: ${fileLocalPath}`)
|
|
5526
|
+
yield downloadFile(fileUrl, fileLocalPath);
|
|
5527
|
+
}
|
|
5528
|
+
}
|
|
5529
|
+
catch (error) {
|
|
5530
|
+
console.error(`Failed to fetch files from ${url}:`, error);
|
|
5531
|
+
}
|
|
5532
|
+
});
|
|
5533
|
+
const confirmFilesExist = (filePaths) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5534
|
+
let everythingDownloaded = false;
|
|
5535
|
+
for (const filePath of filePaths) {
|
|
5536
|
+
const fullPath = path.join(BROWSER_FS_TOP_DIR, filePath);
|
|
5537
|
+
everythingDownloaded = yield fs.promises.exists(fullPath);
|
|
5538
|
+
}
|
|
5539
|
+
if (!everythingDownloaded) {
|
|
5540
|
+
setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
5541
|
+
yield confirmFilesExist(filePaths);
|
|
5542
|
+
}), 500);
|
|
5543
|
+
}
|
|
5544
|
+
});
|
|
5545
|
+
const syncDbFiles = (_a) => __awaiter(void 0, [_a], void 0, function* ({ filePaths, files }) {
|
|
5546
|
+
const fileList = yield fetchDirectory(filePaths);
|
|
5547
|
+
yield fetchFilesRecursively(files, BROWSER_FS_TOP_DIR, fileList);
|
|
5548
|
+
yield confirmFilesExist(fileList);
|
|
5549
|
+
logger$5('[syncDbFiles] Files synced!');
|
|
5550
|
+
});
|
|
5551
|
+
|
|
5552
|
+
const logger$4 = debug('app:files:download');
|
|
5553
|
+
const downloadAllFilesRequestHandler = (_a) => __awaiter(void 0, [_a], void 0, function* ({ endpoints, eventId, }) {
|
|
5554
|
+
yield syncDbFiles(endpoints);
|
|
5555
|
+
eventEmitter.emit('fs.downloadAll.success', { eventId });
|
|
5556
|
+
eventEmitter.emit('fs.downloadAllBinary.request', { endpoints });
|
|
5557
|
+
});
|
|
5558
|
+
const downloadAllFilesBinaryRequestHandler = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5559
|
+
const addresses = yield getAddressesFromDb();
|
|
5560
|
+
const { filesMetadata } = yield queryClient.fetchQuery({
|
|
5561
|
+
queryKey: ['getFilesMetadata', ...addresses],
|
|
5562
|
+
queryFn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5563
|
+
return easClient.request(GET_FILES_METADATA, {
|
|
5564
|
+
where: {
|
|
5565
|
+
attester: {
|
|
5566
|
+
in: addresses,
|
|
5567
|
+
},
|
|
5568
|
+
schema: {
|
|
5569
|
+
is: {
|
|
5570
|
+
id: {
|
|
5571
|
+
equals: '0x55fdefb36fcbbaebeb7d6b41dc3a1a9666e4e42154267c889de064faa7ede517',
|
|
5572
|
+
},
|
|
5573
|
+
},
|
|
5574
|
+
},
|
|
5575
|
+
},
|
|
5576
|
+
});
|
|
5577
|
+
}),
|
|
5578
|
+
});
|
|
5579
|
+
if (!(yield fs.promises.exists('/files'))) {
|
|
5580
|
+
yield fs.promises.mkdir('/files', { recursive: true });
|
|
5581
|
+
}
|
|
5582
|
+
if (!(yield fs.promises.exists('/files/html'))) {
|
|
5583
|
+
yield fs.promises.mkdir('/files/html', { recursive: true });
|
|
5584
|
+
}
|
|
5585
|
+
if (!(yield fs.promises.exists('/files/json'))) {
|
|
5586
|
+
yield fs.promises.mkdir('/files/json', { recursive: true });
|
|
5587
|
+
}
|
|
5588
|
+
if (!(yield fs.promises.exists('/files/images'))) {
|
|
5589
|
+
yield fs.promises.mkdir('/files/images', { recursive: true });
|
|
5590
|
+
}
|
|
5591
|
+
const seedDb = getDb(DB_NAME_SEED);
|
|
5592
|
+
if (!seedDb) {
|
|
5593
|
+
console.warn('[fetchAll/actors] [fetchAllBinaryData] seedDb not available');
|
|
5594
|
+
return [];
|
|
5595
|
+
}
|
|
5596
|
+
for (const fileMetadata of filesMetadata) {
|
|
5597
|
+
const json = JSON.parse(fileMetadata.decodedDataJson);
|
|
5598
|
+
const transactionId = json[0].value.value;
|
|
5599
|
+
const excludedTransactionsQuery = yield seedDb
|
|
5600
|
+
.select()
|
|
5601
|
+
.from(appState)
|
|
5602
|
+
.where(eq(appState.key, 'excludedTransactions'));
|
|
5603
|
+
let excludedTransactions = new Set();
|
|
5604
|
+
if (excludedTransactionsQuery && excludedTransactionsQuery.length === 1) {
|
|
5605
|
+
const valueString = excludedTransactionsQuery[0].value;
|
|
5606
|
+
if (valueString) {
|
|
5607
|
+
const excludedTransactionsArray = JSON.parse(valueString);
|
|
5608
|
+
excludedTransactions = new Set(excludedTransactionsArray);
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5611
|
+
if (excludedTransactions.has(transactionId)) {
|
|
5612
|
+
continue;
|
|
5613
|
+
}
|
|
5614
|
+
const arweave = getArweave();
|
|
5615
|
+
if (!arweave) {
|
|
5616
|
+
console.warn('[fetchAll/actors] [fetchAllBinaryData] arweave not available');
|
|
5617
|
+
return [];
|
|
5618
|
+
}
|
|
5619
|
+
try {
|
|
5620
|
+
const res = yield fetch(`https://${ARWEAVE_HOST}/tx/${transactionId}/status`);
|
|
5621
|
+
if (res.status !== 200) {
|
|
5622
|
+
logger$4(`[fetchAll/actors] [fetchAllBinaryData] error fetching transaction data for ${transactionId}`);
|
|
5623
|
+
excludedTransactions.add(transactionId);
|
|
5624
|
+
yield writeAppState(seedDb, 'excludedTransactions', JSON.stringify(Array.from(excludedTransactions)));
|
|
5625
|
+
continue;
|
|
5626
|
+
}
|
|
5627
|
+
const dataString = yield arweave.transactions
|
|
5628
|
+
.getData(transactionId, {
|
|
5629
|
+
decode: true,
|
|
5630
|
+
string: true,
|
|
5631
|
+
})
|
|
5632
|
+
.catch((error) => {
|
|
5633
|
+
console.error(`[fetchAll/actors] [fetchAllBinaryData] error fetching transaction data for ${transactionId}`, error);
|
|
5634
|
+
});
|
|
5635
|
+
if (!dataString) {
|
|
5636
|
+
logger$4(`[fetchAll/actors] [fetchAllBinaryData] transaction ${transactionId} data not found`);
|
|
5637
|
+
}
|
|
5638
|
+
let contentType = identifyString(dataString);
|
|
5639
|
+
if (contentType !== 'json' &&
|
|
5640
|
+
contentType !== 'base64' &&
|
|
5641
|
+
contentType !== 'html') {
|
|
5642
|
+
const possibleImageType = getImageDataType(dataString);
|
|
5643
|
+
if (!possibleImageType) {
|
|
5644
|
+
logger$4(`[fetchAll/actors] [fetchAllBinaryData] transaction ${transactionId} data not in expected format: ${possibleImageType}`);
|
|
5645
|
+
continue;
|
|
5646
|
+
}
|
|
5647
|
+
contentType = possibleImageType;
|
|
5648
|
+
}
|
|
5649
|
+
if (contentType === 'url') {
|
|
5650
|
+
const url = dataString;
|
|
5651
|
+
const response = yield fetch(url);
|
|
5652
|
+
if (!response.ok) {
|
|
5653
|
+
throw new Error(`Failed to fetch image: ${response.statusText}`);
|
|
5654
|
+
}
|
|
5655
|
+
// Get the image as a Blob
|
|
5656
|
+
const blob = yield response.blob();
|
|
5657
|
+
const buffer = yield blob.arrayBuffer();
|
|
5658
|
+
const bufferUint8Array = new Uint8Array(buffer);
|
|
5659
|
+
// Extract the file extension from the URL
|
|
5660
|
+
const extensionMatch = url.match(/\.(jpg|jpeg|png|gif|bmp|webp|svg)$/i);
|
|
5661
|
+
if (!extensionMatch) {
|
|
5662
|
+
throw new Error('Unable to determine the file extension from the URL.');
|
|
5663
|
+
}
|
|
5664
|
+
const fileExtension = extensionMatch[0]; // e.g., ".jpg"
|
|
5665
|
+
// Set the file name (you can customize this)
|
|
5666
|
+
// const fileNameFromUrl = `${transactionId}${fileExtension}`
|
|
5667
|
+
yield fs.promises.writeFile(`/files/images/${transactionId}`, bufferUint8Array, {
|
|
5668
|
+
encoding: 'binary',
|
|
5669
|
+
});
|
|
5670
|
+
continue;
|
|
5671
|
+
}
|
|
5672
|
+
const mimeType = getMimeType(dataString);
|
|
5673
|
+
let fileName = transactionId;
|
|
5674
|
+
if (contentType === 'base64') {
|
|
5675
|
+
if (mimeType) {
|
|
5676
|
+
fileName += `.${mimeType}`;
|
|
5677
|
+
}
|
|
5678
|
+
// Remove the Base64 header if it exists (e.g., "data:image/png;base64,")
|
|
5679
|
+
const base64Data = dataString.split(',').pop() || '';
|
|
5680
|
+
// Decode the Base64 string to binary
|
|
5681
|
+
const binaryString = atob(base64Data);
|
|
5682
|
+
const length = binaryString.length;
|
|
5683
|
+
const binaryData = new Uint8Array(length);
|
|
5684
|
+
for (let i = 0; i < length; i++) {
|
|
5685
|
+
binaryData[i] = binaryString.charCodeAt(i);
|
|
5686
|
+
}
|
|
5687
|
+
yield fs.promises.writeFile(`/files/images/${fileName}`, binaryData, {
|
|
5688
|
+
encoding: 'binary',
|
|
5689
|
+
});
|
|
5690
|
+
// if (dataUint8Array && dataUint8Array instanceof Uint8Array) {
|
|
5691
|
+
// await fs.promises.writeFile(
|
|
5692
|
+
// `/files/images/${fileName}`,
|
|
5693
|
+
// dataUint8Array,
|
|
5694
|
+
// )
|
|
5695
|
+
// }
|
|
5696
|
+
}
|
|
5697
|
+
if (contentType === 'html') {
|
|
5698
|
+
fileName += '.html';
|
|
5699
|
+
yield fs.promises.writeFile(`/files/html/${fileName}`, dataString);
|
|
5700
|
+
}
|
|
5701
|
+
if (contentType === 'json') {
|
|
5702
|
+
fileName += '.json';
|
|
5703
|
+
yield fs.promises.writeFile(`/files/json/${fileName}`, dataString);
|
|
5704
|
+
}
|
|
5705
|
+
}
|
|
5706
|
+
catch (error) {
|
|
5707
|
+
logger$4(error);
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
});
|
|
5711
|
+
|
|
5712
|
+
let isInitialized = false;
|
|
5713
|
+
const fsInitHandler = (_) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5714
|
+
if (isInitialized) {
|
|
5715
|
+
eventEmitter.emit('fs.init.response', { success: true });
|
|
5716
|
+
return;
|
|
5717
|
+
}
|
|
5718
|
+
try {
|
|
5719
|
+
const handle = yield navigator.storage.getDirectory();
|
|
5720
|
+
// await configure({ backend: WebAccess, handle })
|
|
5721
|
+
yield configureSingle({
|
|
5722
|
+
backend: WebAccess,
|
|
5723
|
+
handle,
|
|
5724
|
+
});
|
|
5725
|
+
isInitialized = true;
|
|
5726
|
+
eventEmitter.emit('fs.init.response', { success: true });
|
|
5727
|
+
}
|
|
5728
|
+
catch (e) {
|
|
5729
|
+
if (!isInitialized) {
|
|
5730
|
+
console.error('[fs.init] error initializing fs', e);
|
|
5731
|
+
eventEmitter.emit('fs.init.response', {
|
|
5732
|
+
success: false,
|
|
5733
|
+
error: e,
|
|
5734
|
+
});
|
|
5735
|
+
}
|
|
5736
|
+
// TODO: We can ignore this for now but should figure out if this is being called excessively
|
|
5737
|
+
}
|
|
5738
|
+
});
|
|
5739
|
+
let areReady = false;
|
|
5740
|
+
const setupFsListeners = () => {
|
|
5741
|
+
eventEmitter.addListener('fs.downloadAll.request', downloadAllFilesRequestHandler);
|
|
5742
|
+
eventEmitter.addListener('fs.downloadAllBinary.request', downloadAllFilesBinaryRequestHandler);
|
|
5743
|
+
eventEmitter.addListener('fs.init', fsInitHandler);
|
|
5744
|
+
areReady = true;
|
|
5745
|
+
};
|
|
5746
|
+
const areFsListenersReady = () => {
|
|
5747
|
+
return areReady;
|
|
5748
|
+
};
|
|
5749
|
+
const isFsInitialized = () => {
|
|
5750
|
+
return isInitialized;
|
|
5751
|
+
};
|
|
5752
|
+
|
|
5753
|
+
const logger$3 = debug('app:internal:actors');
|
|
5754
|
+
let sqliteWasmClient;
|
|
5755
|
+
let manager;
|
|
5756
|
+
const validateInput = fromCallback(({ sendBack, input: { event } }) => {
|
|
5757
|
+
const { endpoints, addresses } = event;
|
|
5758
|
+
if (typeof window === 'undefined') {
|
|
5759
|
+
throw new Error('validateInput called from non-browser context');
|
|
5760
|
+
}
|
|
5761
|
+
if (!endpoints || !endpoints.filePaths || !endpoints.files) {
|
|
5762
|
+
throw new Error('validateInput called with invalid endpoints');
|
|
5763
|
+
}
|
|
5764
|
+
if (!addresses || !addresses.length) {
|
|
5765
|
+
throw new Error('validateInput called with invalid addresses');
|
|
5766
|
+
}
|
|
5767
|
+
const _validateInput = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5768
|
+
sendBack({
|
|
5769
|
+
type: INTERNAL_VALIDATING_INPUT_SUCCESS,
|
|
5770
|
+
endpoints,
|
|
5771
|
+
addresses,
|
|
5772
|
+
});
|
|
5773
|
+
});
|
|
5774
|
+
_validateInput().then(() => {
|
|
5775
|
+
return;
|
|
5776
|
+
});
|
|
5777
|
+
});
|
|
5778
|
+
const prepareDb = fromCallback(({ sendBack, input: { event, context } }) => {
|
|
5779
|
+
const _prepareDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5780
|
+
if (typeof window === 'undefined') {
|
|
5781
|
+
return;
|
|
5782
|
+
}
|
|
5783
|
+
sqliteWasmClient = yield getSqlite();
|
|
5784
|
+
});
|
|
5785
|
+
const interval = setInterval(() => {
|
|
5786
|
+
// TODO: Add a timeout
|
|
5787
|
+
// TODO: Add a cancel token to the promise so we can prevent more loops starting while we're checking the successful outcome
|
|
5788
|
+
if (sqliteWasmClient) {
|
|
5789
|
+
clearInterval(interval);
|
|
5790
|
+
manager = new SqliteConnectionManager(sqliteWasmClient);
|
|
5791
|
+
sendBack({ type: 'prepareDbSuccess', manager });
|
|
5792
|
+
return;
|
|
5793
|
+
}
|
|
5794
|
+
_prepareDb().then(() => {
|
|
5795
|
+
return;
|
|
5796
|
+
});
|
|
5797
|
+
}, 500);
|
|
5798
|
+
return () => {
|
|
5799
|
+
if (interval) {
|
|
5800
|
+
clearInterval(interval);
|
|
5801
|
+
}
|
|
5802
|
+
};
|
|
5803
|
+
});
|
|
5804
|
+
const configureFs = fromCallback(({ sendBack, input: { context } }) => {
|
|
5805
|
+
const { endpoints, seedDbService, appDbService, sdkDbService } = context;
|
|
5806
|
+
logger$3('[internal/actors] [configureFs] Configuring FS');
|
|
5807
|
+
const services = [seedDbService, appDbService, sdkDbService];
|
|
5808
|
+
const _configureFs = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5809
|
+
logger$3('[internal/actors] [configureFs] calling _configureFs');
|
|
5810
|
+
logger$3('[internal/actors] [configureFs] areFsListenersReady:', areFsListenersReady());
|
|
5811
|
+
logger$3('[internal/actors] [configureFs] isFsInitialized:', isFsInitialized());
|
|
5812
|
+
yield waitForEvent({
|
|
5813
|
+
req: {
|
|
5814
|
+
eventLabel: 'fs.downloadAll.request',
|
|
5815
|
+
data: { endpoints },
|
|
5816
|
+
},
|
|
5817
|
+
res: {
|
|
5818
|
+
eventLabel: 'fs.downloadAll.success',
|
|
5819
|
+
},
|
|
5820
|
+
});
|
|
5821
|
+
yield Promise.all(services.map((service) => __awaiter(void 0, void 0, void 0, function* () {
|
|
5822
|
+
const { dirName } = service.getSnapshot().context;
|
|
5823
|
+
const journalPath = `${BROWSER_FS_TOP_DIR}/${dirName}/db/meta/_journal.json`;
|
|
5824
|
+
const journalExists = yield fs.promises.exists(journalPath);
|
|
5825
|
+
if (journalExists) {
|
|
5826
|
+
service.send({ type: DB_WAITING_FOR_FILES_RECEIVED });
|
|
5827
|
+
}
|
|
5828
|
+
// return new Promise<void>((resolve) => {
|
|
5829
|
+
// const interval = setInterval(() => {
|
|
5830
|
+
// journalExistsSync = fs.existsSync(journalPath)
|
|
5831
|
+
// logger(
|
|
5832
|
+
// '[internal/actors] [configureFs] journalExistsSync:',
|
|
5833
|
+
// journalExistsSync,
|
|
5834
|
+
// )
|
|
5835
|
+
// if (journalExistsSync) {
|
|
5836
|
+
// service.send({ type: DB_WAITING_FOR_FILES_RECEIVED })
|
|
5837
|
+
// clearInterval(interval)
|
|
5838
|
+
// resolve()
|
|
5839
|
+
// }
|
|
5840
|
+
// }, 200)
|
|
5841
|
+
// })
|
|
5842
|
+
})));
|
|
5843
|
+
logger$3('[internal/actors] [configureFs] fs configured!');
|
|
5844
|
+
});
|
|
5845
|
+
// Some of our dependencies use fs sync functions, which don't work with
|
|
5846
|
+
// OPFS. ZenFS creates an async cache of all files so that the sync functions
|
|
5847
|
+
// work, but we have to wait for it to be built. Otherwise things like
|
|
5848
|
+
// drizzleMigrate will fail since they can't see the migration files yet.
|
|
5849
|
+
_configureFs().then(() => {
|
|
5850
|
+
sendBack({ type: INTERNAL_CONFIGURING_FS_SUCCESS });
|
|
5851
|
+
return;
|
|
5852
|
+
});
|
|
5853
|
+
return () => { };
|
|
5854
|
+
});
|
|
5855
|
+
const loadSeedDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
5856
|
+
const { seedDbService } = context;
|
|
5857
|
+
if (seedDbService.getSnapshot().value === 'ready') {
|
|
5858
|
+
sendBack({ type: INTERNAL_LOADING_SEED_DB_SUCCESS });
|
|
5859
|
+
return () => { };
|
|
5860
|
+
}
|
|
5861
|
+
let subscription;
|
|
5862
|
+
const _loadSeedDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5863
|
+
yield waitFor(seedDbService, (snapshot) => snapshot.value === 'ready');
|
|
5864
|
+
subscription = seedDbService.subscribe({
|
|
5865
|
+
next: (snapshot) => {
|
|
5866
|
+
sendBack({ type: DB_ON_SNAPSHOT, dbName: DB_NAME_SEED, snapshot });
|
|
5867
|
+
},
|
|
5868
|
+
});
|
|
5869
|
+
});
|
|
5870
|
+
_loadSeedDb().then(() => {
|
|
5871
|
+
sendBack({ type: INTERNAL_LOADING_SEED_DB_SUCCESS });
|
|
5872
|
+
});
|
|
5873
|
+
return () => {
|
|
5874
|
+
if (subscription) {
|
|
5875
|
+
subscription.unsubscribe();
|
|
5876
|
+
}
|
|
5877
|
+
};
|
|
5878
|
+
});
|
|
5879
|
+
const saveConfig = fromCallback(({ sendBack, receive, input: { context } }) => {
|
|
5880
|
+
if (typeof window === 'undefined') {
|
|
5881
|
+
console.error('seedInitBrowser called from non-browser context');
|
|
5882
|
+
sendBack({
|
|
5883
|
+
type: 'error',
|
|
5884
|
+
error: 'Browser method called from non-browser context',
|
|
5885
|
+
});
|
|
5886
|
+
}
|
|
5887
|
+
const { endpoints, addresses } = context;
|
|
5888
|
+
if (!endpoints) {
|
|
5889
|
+
throw new Error('saveConfig called with invalid endpoints');
|
|
5890
|
+
}
|
|
5891
|
+
const _saveConfig = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5892
|
+
// logger('[sdk] [internal/actors] starting _saveConfig')
|
|
5893
|
+
const seedDb = getDb(DB_NAME_SEED);
|
|
5894
|
+
if (!seedDb) {
|
|
5895
|
+
throw new Error('Seed DB not found');
|
|
5896
|
+
}
|
|
5897
|
+
const endpointsValueString = JSON.stringify(endpoints);
|
|
5898
|
+
const addressesValueString = JSON.stringify(addresses);
|
|
5899
|
+
// TODO: Figure out how to define on conflict with multiple rows added
|
|
5900
|
+
try {
|
|
5901
|
+
// logger('[sdk] [internal/actors] Saving endpoints to db')
|
|
5902
|
+
yield seedDb
|
|
5903
|
+
.insert(appState)
|
|
5904
|
+
.values({
|
|
5905
|
+
key: 'endpoints',
|
|
5906
|
+
value: endpointsValueString,
|
|
5907
|
+
})
|
|
5908
|
+
.onConflictDoUpdate({
|
|
5909
|
+
target: appState.key,
|
|
5910
|
+
set: {
|
|
5911
|
+
value: endpointsValueString,
|
|
5912
|
+
},
|
|
5913
|
+
setWhere: sql `key = 'endpoints'`,
|
|
5914
|
+
});
|
|
5915
|
+
// logger('[sdk] [internal/actors] Saving addresses to db')
|
|
5916
|
+
yield seedDb
|
|
5917
|
+
.insert(appState)
|
|
5918
|
+
.values({
|
|
5919
|
+
key: 'addresses',
|
|
5920
|
+
value: addressesValueString,
|
|
5921
|
+
})
|
|
5922
|
+
.onConflictDoUpdate({
|
|
5923
|
+
target: appState.key,
|
|
5924
|
+
set: {
|
|
5925
|
+
value: addressesValueString,
|
|
5926
|
+
},
|
|
5927
|
+
setWhere: sql `key = 'addresses'`,
|
|
5928
|
+
});
|
|
5929
|
+
logger$3('[sdk] [internal/actors] Should be done saving');
|
|
5930
|
+
}
|
|
5931
|
+
catch (error) {
|
|
5932
|
+
console.error('Error saving config:', error);
|
|
5933
|
+
}
|
|
5934
|
+
});
|
|
5935
|
+
_saveConfig().then(() => {
|
|
5936
|
+
logger$3('[sdk] [internal/actors] Successfully saved config');
|
|
5937
|
+
return sendBack({ type: INTERNAL_SAVING_CONFIG_SUCCESS });
|
|
5938
|
+
});
|
|
5939
|
+
return () => { };
|
|
5940
|
+
});
|
|
5941
|
+
const loadAppDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
5942
|
+
const { appDbService } = context;
|
|
5943
|
+
let subscription;
|
|
5944
|
+
const _loadAppDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5945
|
+
return new Promise((resolve) => {
|
|
5946
|
+
if (appDbService.getSnapshot().value === 'ready') {
|
|
5947
|
+
return resolve();
|
|
5948
|
+
}
|
|
5949
|
+
subscription = appDbService.subscribe({
|
|
5950
|
+
next: (snapshot) => {
|
|
5951
|
+
if (snapshot.value === 'ready') {
|
|
5952
|
+
return resolve();
|
|
5953
|
+
}
|
|
5954
|
+
sendBack({ type: DB_ON_SNAPSHOT, dbName: DB_NAME_APP, snapshot });
|
|
5955
|
+
},
|
|
5956
|
+
});
|
|
5957
|
+
});
|
|
5958
|
+
});
|
|
5959
|
+
_loadAppDb().then(() => {
|
|
5960
|
+
sendBack({ type: INTERNAL_LOADING_APP_DB_SUCCESS });
|
|
5961
|
+
logger$3('[sdk] [internal/actors] Successfully loaded app DB');
|
|
5962
|
+
});
|
|
5963
|
+
return () => {
|
|
5964
|
+
if (subscription) {
|
|
5965
|
+
subscription.unsubscribe();
|
|
5966
|
+
}
|
|
5967
|
+
};
|
|
5968
|
+
});
|
|
5969
|
+
const loadSdkDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
5970
|
+
const { sdkDbService } = context;
|
|
5971
|
+
logger$3('[sdk] [internal/actors] Loading SDK DB');
|
|
5972
|
+
let subscription;
|
|
5973
|
+
const _loadSdkDb = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
5974
|
+
return new Promise((resolve) => {
|
|
5975
|
+
if (sdkDbService.getSnapshot().value === 'ready') {
|
|
5976
|
+
return resolve();
|
|
5977
|
+
}
|
|
5978
|
+
subscription = sdkDbService.subscribe({
|
|
5979
|
+
next: (snapshot) => {
|
|
5980
|
+
if (snapshot.value === 'ready') {
|
|
5981
|
+
return resolve();
|
|
5982
|
+
}
|
|
5983
|
+
sendBack({
|
|
5984
|
+
type: DB_ON_SNAPSHOT,
|
|
5985
|
+
dbName: DB_NAME_SDK_CONFIG,
|
|
5986
|
+
snapshot,
|
|
5987
|
+
});
|
|
5988
|
+
},
|
|
5989
|
+
});
|
|
5990
|
+
});
|
|
5991
|
+
});
|
|
5992
|
+
_loadSdkDb().then(() => {
|
|
5993
|
+
sendBack({ type: INTERNAL_LOADING_SDK_DB_SUCCESS });
|
|
5994
|
+
logger$3('[sdk] [internal/actors] Successfully loaded SDK DB');
|
|
5995
|
+
});
|
|
5996
|
+
return () => {
|
|
5997
|
+
if (subscription) {
|
|
5998
|
+
subscription.unsubscribe();
|
|
5999
|
+
}
|
|
6000
|
+
};
|
|
6001
|
+
});
|
|
6002
|
+
|
|
6003
|
+
const logger$2 = debug('app:services:db:machine');
|
|
5578
6004
|
const { CHECKING_STATUS, VALIDATING, WAITING_FOR_FILES, CONNECTING_TO_DB, MIGRATING, } = DbState;
|
|
5579
6005
|
const dbMachine = setup({
|
|
5580
6006
|
types: {
|
|
@@ -5595,7 +6021,7 @@ const dbMachine = setup({
|
|
|
5595
6021
|
[DB_WAITING_FOR_FILES_RECEIVED]: {
|
|
5596
6022
|
actions: assign({
|
|
5597
6023
|
hasFiles: ({ event }) => {
|
|
5598
|
-
logger$
|
|
6024
|
+
logger$2('[db/machine] DB_WAITING_FOR_FILES_RECEIVED event:', event);
|
|
5599
6025
|
return true;
|
|
5600
6026
|
},
|
|
5601
6027
|
}),
|
|
@@ -5604,8 +6030,8 @@ const dbMachine = setup({
|
|
|
5604
6030
|
target: `.${CHECKING_STATUS}`,
|
|
5605
6031
|
actions: assign({
|
|
5606
6032
|
hasFiles: ({ context, event }) => {
|
|
5607
|
-
logger$
|
|
5608
|
-
logger$
|
|
6033
|
+
logger$2('[db/machine] updateHasFiles event:', event);
|
|
6034
|
+
logger$2('[db/machine] updateHasFiles context:', context);
|
|
5609
6035
|
return event.hasFiles;
|
|
5610
6036
|
},
|
|
5611
6037
|
}),
|
|
@@ -5726,7 +6152,7 @@ const dbMachine = setup({
|
|
|
5726
6152
|
},
|
|
5727
6153
|
});
|
|
5728
6154
|
|
|
5729
|
-
const logger$
|
|
6155
|
+
const logger$1 = debug('app:services:internal:machine');
|
|
5730
6156
|
createBrowserInspector({
|
|
5731
6157
|
autoStart: false,
|
|
5732
6158
|
});
|
|
@@ -5888,7 +6314,7 @@ const internalMachine = setup({
|
|
|
5888
6314
|
[INTERNAL_LOADING_APP_DB_SUCCESS]: {
|
|
5889
6315
|
target: 'appDbLoaded',
|
|
5890
6316
|
actions: () => {
|
|
5891
|
-
logger$
|
|
6317
|
+
logger$1('[sdk] [internal/index] App DB loaded!');
|
|
5892
6318
|
},
|
|
5893
6319
|
},
|
|
5894
6320
|
},
|
|
@@ -5900,7 +6326,7 @@ const internalMachine = setup({
|
|
|
5900
6326
|
appDbLoaded: {
|
|
5901
6327
|
type: 'final',
|
|
5902
6328
|
entry: () => {
|
|
5903
|
-
logger$
|
|
6329
|
+
logger$1('[sdk] [internal/index] Entered appDbLoaded!');
|
|
5904
6330
|
},
|
|
5905
6331
|
},
|
|
5906
6332
|
},
|
|
@@ -5913,7 +6339,7 @@ const internalMachine = setup({
|
|
|
5913
6339
|
[INTERNAL_LOADING_SDK_DB_SUCCESS]: {
|
|
5914
6340
|
target: 'sdkConfigDbLoaded',
|
|
5915
6341
|
actions: () => {
|
|
5916
|
-
logger$
|
|
6342
|
+
logger$1('[sdk] [internal/index] SDK Config DB loaded!');
|
|
5917
6343
|
},
|
|
5918
6344
|
},
|
|
5919
6345
|
},
|
|
@@ -5925,7 +6351,7 @@ const internalMachine = setup({
|
|
|
5925
6351
|
sdkConfigDbLoaded: {
|
|
5926
6352
|
type: 'final',
|
|
5927
6353
|
entry: () => {
|
|
5928
|
-
logger$
|
|
6354
|
+
logger$1('[sdk] [internal/index] Entered sdkConfigDbLoaded!');
|
|
5929
6355
|
},
|
|
5930
6356
|
},
|
|
5931
6357
|
},
|
|
@@ -5934,7 +6360,7 @@ const internalMachine = setup({
|
|
|
5934
6360
|
onDone: {
|
|
5935
6361
|
target: 'ready',
|
|
5936
6362
|
actions: () => {
|
|
5937
|
-
logger$
|
|
6363
|
+
logger$1('[sdk] [internal/index] All DBs loaded! Should be headed to ready');
|
|
5938
6364
|
eventEmitter.emit('allDbsLoaded');
|
|
5939
6365
|
},
|
|
5940
6366
|
},
|
|
@@ -5946,7 +6372,7 @@ const internalMachine = setup({
|
|
|
5946
6372
|
},
|
|
5947
6373
|
ready: {
|
|
5948
6374
|
entry: () => {
|
|
5949
|
-
logger$
|
|
6375
|
+
logger$1('[sdk] [internal/index] Ready!');
|
|
5950
6376
|
},
|
|
5951
6377
|
meta: {
|
|
5952
6378
|
displayText: "Crossing the t's ...",
|
|
@@ -5961,7 +6387,7 @@ const internalMachine = setup({
|
|
|
5961
6387
|
},
|
|
5962
6388
|
},
|
|
5963
6389
|
entry: () => {
|
|
5964
|
-
logger$
|
|
6390
|
+
logger$1('[sdk] [internal/index] Error!');
|
|
5965
6391
|
},
|
|
5966
6392
|
meta: {
|
|
5967
6393
|
displayText: 'Whoops! Something went wrong.',
|
|
@@ -6057,464 +6483,149 @@ const globalMachine = setup({
|
|
|
6057
6483
|
}),
|
|
6058
6484
|
},
|
|
6059
6485
|
[GLOBAL_INITIALIZING_INTERNAL_SERVICE_READY]: ADDING_MODELS_TO_DB,
|
|
6060
|
-
},
|
|
6061
|
-
invoke: {
|
|
6062
|
-
src: 'initialize',
|
|
6063
|
-
input: ({ event, context }) => ({ event, context }),
|
|
6064
|
-
meta: {
|
|
6065
|
-
displayText: 'Initializing Seed SDK',
|
|
6066
|
-
percentComplete: 10,
|
|
6067
|
-
},
|
|
6068
|
-
tags: ['loading'],
|
|
6069
|
-
},
|
|
6070
|
-
},
|
|
6071
|
-
[ADDING_MODELS_TO_DB]: {
|
|
6072
|
-
on: {
|
|
6073
|
-
[GLOBAL_ADDING_MODELS_TO_DB_SUCCESS]: {
|
|
6074
|
-
target: INITIALIZED,
|
|
6075
|
-
actions: assign({
|
|
6076
|
-
addedModelRecordsToDb: true,
|
|
6077
|
-
}),
|
|
6078
|
-
},
|
|
6079
|
-
},
|
|
6080
|
-
invoke: {
|
|
6081
|
-
src: 'addModelsToDb',
|
|
6082
|
-
input: ({ context }) => ({ context }),
|
|
6083
|
-
meta: {
|
|
6084
|
-
displayText: 'Adding models to database',
|
|
6085
|
-
},
|
|
6086
|
-
tags: ['loading'],
|
|
6087
|
-
},
|
|
6088
|
-
},
|
|
6089
|
-
[INITIALIZED]: {
|
|
6090
|
-
type: 'parallel',
|
|
6091
|
-
on: {
|
|
6092
|
-
getSeedClass: `.${GETTING_SEED_CLASS}`,
|
|
6093
|
-
getSchemaForModel: `.${GETTING_SCHEMA_FOR_MODEL}`,
|
|
6094
|
-
},
|
|
6095
|
-
meta: {
|
|
6096
|
-
displayText: 'Global service ready',
|
|
6097
|
-
percentComplete: 40,
|
|
6098
|
-
},
|
|
6099
|
-
tags: ['loading'],
|
|
6100
|
-
states: {
|
|
6101
|
-
[GETTING_SEED_CLASS]: {
|
|
6102
|
-
entry: [
|
|
6103
|
-
(_a) => __awaiter(void 0, [_a], void 0, function* ({ context }) {
|
|
6104
|
-
let SeedClass;
|
|
6105
|
-
if (context.environment === 'node') {
|
|
6106
|
-
const { SeedNode } = yield import('./seed-BYEGj3gH.js');
|
|
6107
|
-
SeedClass = SeedNode;
|
|
6108
|
-
}
|
|
6109
|
-
else {
|
|
6110
|
-
const { SeedBrowser } = yield import('./seed-BTpkUOtG.js');
|
|
6111
|
-
SeedClass = SeedBrowser;
|
|
6112
|
-
}
|
|
6113
|
-
return SeedClass;
|
|
6114
|
-
}),
|
|
6115
|
-
],
|
|
6116
|
-
meta: {
|
|
6117
|
-
displayText: 'Getting SeedClass',
|
|
6118
|
-
},
|
|
6119
|
-
tags: ['loading'],
|
|
6120
|
-
},
|
|
6121
|
-
[GETTING_SCHEMA_FOR_MODEL]: {
|
|
6122
|
-
invoke: {
|
|
6123
|
-
src: 'getSchemaForModel',
|
|
6124
|
-
input: ({ event, context }) => ({ event, context }),
|
|
6125
|
-
meta: {
|
|
6126
|
-
displayText: 'Getting schema for model',
|
|
6127
|
-
},
|
|
6128
|
-
tags: ['loading'],
|
|
6129
|
-
},
|
|
6486
|
+
},
|
|
6487
|
+
invoke: {
|
|
6488
|
+
src: 'initialize',
|
|
6489
|
+
input: ({ event, context }) => ({ event, context }),
|
|
6490
|
+
meta: {
|
|
6491
|
+
displayText: 'Initializing Seed SDK',
|
|
6492
|
+
percentComplete: 10,
|
|
6130
6493
|
},
|
|
6494
|
+
tags: ['loading'],
|
|
6131
6495
|
},
|
|
6132
6496
|
},
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
}
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
// return
|
|
6171
|
-
// }
|
|
6172
|
-
// if (inspEvent.snapshot && inspEvent.snapshot.value) {
|
|
6173
|
-
// if (typeof window !== 'undefined') {
|
|
6174
|
-
// eventEmitter.emit('globalService', {
|
|
6175
|
-
// type: eventType,
|
|
6176
|
-
// src: srcId,
|
|
6177
|
-
// snapshot: inspEvent.snapshot,
|
|
6178
|
-
// })
|
|
6179
|
-
// }
|
|
6180
|
-
// }
|
|
6181
|
-
// } else {
|
|
6182
|
-
// if (typeof window !== 'undefined') {
|
|
6183
|
-
// let snapshot
|
|
6184
|
-
//
|
|
6185
|
-
// try {
|
|
6186
|
-
// snapshot = inspEvent.actorRef.getSnapshot()
|
|
6187
|
-
// } catch (e) {
|
|
6188
|
-
// // This fails if the actor hasn't initialized yet, but that's OK I think
|
|
6189
|
-
// // console.log('[sdk] [service/index] ERROR', e)
|
|
6190
|
-
// }
|
|
6191
|
-
//
|
|
6192
|
-
// eventEmitter.emit('globalService', {
|
|
6193
|
-
// type: eventType,
|
|
6194
|
-
// src: srcId,
|
|
6195
|
-
// snapshot,
|
|
6196
|
-
// })
|
|
6197
|
-
// }
|
|
6198
|
-
// }
|
|
6199
|
-
},
|
|
6200
|
-
});
|
|
6201
|
-
globalService.start();
|
|
6202
|
-
const getGlobalService = () => globalService;
|
|
6203
|
-
|
|
6204
|
-
const logger$1 = debug('app:react:index');
|
|
6205
|
-
const useItemProperty = (propertyName, seedLocalId) => {
|
|
6206
|
-
const [property, setProperty] = useImmer(undefined);
|
|
6207
|
-
const [isReadingFromDb, setIsReadingFromDb] = useState(false);
|
|
6208
|
-
const [isInitialized, setIsInitialized] = useState(false);
|
|
6209
|
-
const value = useSelector(property === null || property === void 0 ? void 0 : property.getService(), (snapshot) => {
|
|
6210
|
-
if (!snapshot || !snapshot.context) {
|
|
6211
|
-
return;
|
|
6212
|
-
}
|
|
6213
|
-
return snapshot.context.renderValue || snapshot.context.propertyValue;
|
|
6214
|
-
});
|
|
6215
|
-
const status = useSelector(property === null || property === void 0 ? void 0 : property.getService(), (snapshot) => snapshot === null || snapshot === void 0 ? void 0 : snapshot.value);
|
|
6216
|
-
useEffect(() => {
|
|
6217
|
-
if (property && property.value !== value) {
|
|
6218
|
-
readFromDb();
|
|
6219
|
-
}
|
|
6220
|
-
}, [property, value]);
|
|
6221
|
-
const readFromDb = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
6222
|
-
if (isReadingFromDb) {
|
|
6223
|
-
return;
|
|
6224
|
-
}
|
|
6225
|
-
setIsReadingFromDb(true);
|
|
6226
|
-
const foundProperty = yield ItemProperty.find({ propertyName, seedLocalId });
|
|
6227
|
-
setIsReadingFromDb(false);
|
|
6228
|
-
if (!foundProperty) {
|
|
6229
|
-
logger$1(`[useItemPropertyTest] [readFromDb] no property found for Item.${seedLocalId}.${propertyName}`);
|
|
6230
|
-
return;
|
|
6231
|
-
}
|
|
6232
|
-
setProperty(() => foundProperty);
|
|
6233
|
-
setIsInitialized(true);
|
|
6234
|
-
}), [isReadingFromDb]);
|
|
6235
|
-
useEffect(() => {
|
|
6236
|
-
readFromDb();
|
|
6237
|
-
}, []);
|
|
6238
|
-
// TODO: How can we force a re-render when the property is updated?
|
|
6239
|
-
// Right now, the value will trigger an update because it's using a selector
|
|
6240
|
-
// and a change is pushed to the hook listener.
|
|
6241
|
-
return {
|
|
6242
|
-
property,
|
|
6243
|
-
isInitialized,
|
|
6244
|
-
isReadingFromDb,
|
|
6245
|
-
value,
|
|
6246
|
-
status,
|
|
6247
|
-
};
|
|
6248
|
-
};
|
|
6249
|
-
const useItem = ({ modelName, seedLocalId, seedUid }) => {
|
|
6250
|
-
const [item, setItem] = useImmer(undefined);
|
|
6251
|
-
const [itemSubscription, setItemSubscription] = useState();
|
|
6252
|
-
const { status, internalStatus } = useGlobalServiceStatus();
|
|
6253
|
-
const isReadingDb = useRef(false);
|
|
6254
|
-
const itemStatus = useSelector(item === null || item === void 0 ? void 0 : item.getService(), (snapshot) => snapshot === null || snapshot === void 0 ? void 0 : snapshot.value);
|
|
6255
|
-
const updateItem = useCallback((newItem) => {
|
|
6256
|
-
setItem(() => newItem);
|
|
6257
|
-
}, []);
|
|
6258
|
-
const readFromDb = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
6259
|
-
if (isReadingDb.current ||
|
|
6260
|
-
internalStatus !== 'ready' ||
|
|
6261
|
-
(!seedUid && !seedLocalId)) {
|
|
6262
|
-
return;
|
|
6263
|
-
}
|
|
6264
|
-
isReadingDb.current = true;
|
|
6265
|
-
const foundItem = yield Item.find({
|
|
6266
|
-
modelName,
|
|
6267
|
-
seedLocalId,
|
|
6268
|
-
seedUid,
|
|
6269
|
-
});
|
|
6270
|
-
if (!foundItem) {
|
|
6271
|
-
logger$1('[useItem] [getItemFromDb] no item found', modelName, seedLocalId);
|
|
6272
|
-
return;
|
|
6273
|
-
}
|
|
6274
|
-
updateItem(foundItem);
|
|
6275
|
-
isReadingDb.current = false;
|
|
6276
|
-
}), [internalStatus]);
|
|
6277
|
-
useEffect(() => {
|
|
6278
|
-
if (internalStatus === 'ready') {
|
|
6279
|
-
readFromDb();
|
|
6280
|
-
}
|
|
6281
|
-
}, [internalStatus, status]);
|
|
6282
|
-
useEffect(() => {
|
|
6283
|
-
if (item && !itemSubscription) {
|
|
6284
|
-
const subscription = item.subscribe((_) => __awaiter(void 0, void 0, void 0, function* () {
|
|
6285
|
-
const newItem = yield Item.find({ modelName, seedLocalId, seedUid });
|
|
6286
|
-
if (!newItem) {
|
|
6287
|
-
logger$1('[useItem] [itemSubscription] no item found', modelName, seedLocalId);
|
|
6288
|
-
return;
|
|
6289
|
-
}
|
|
6290
|
-
setItem(() => newItem);
|
|
6291
|
-
}));
|
|
6292
|
-
setItemSubscription(subscription);
|
|
6293
|
-
}
|
|
6294
|
-
return () => {
|
|
6295
|
-
itemSubscription === null || itemSubscription === void 0 ? void 0 : itemSubscription.unsubscribe();
|
|
6296
|
-
};
|
|
6297
|
-
}, [item, itemSubscription]);
|
|
6298
|
-
useEffect(() => {
|
|
6299
|
-
const seedId = seedUid || seedLocalId;
|
|
6300
|
-
eventEmitter.addListener(`item.${modelName}.${seedId}.update`, readFromDb);
|
|
6301
|
-
return () => {
|
|
6302
|
-
eventEmitter.removeListener(`item.${modelName}.${seedId}.update`, readFromDb);
|
|
6303
|
-
};
|
|
6304
|
-
}, []);
|
|
6305
|
-
return {
|
|
6306
|
-
item,
|
|
6307
|
-
itemStatus,
|
|
6308
|
-
};
|
|
6309
|
-
};
|
|
6310
|
-
const useItems = ({ modelName, options }) => {
|
|
6311
|
-
const [items, setItems] = useImmer([]);
|
|
6312
|
-
const [isReadingDb, setIsReadingDb] = useState(false);
|
|
6313
|
-
const [isInitialized, setIsInitialized] = useState(false);
|
|
6314
|
-
const { dbsAreReady } = useDbsAreReady();
|
|
6315
|
-
const modelNameRef = useRef(modelName);
|
|
6316
|
-
const readFromDb = useCallback((event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
6317
|
-
if (!event ||
|
|
6318
|
-
!event.modelName ||
|
|
6319
|
-
event.modelName !== modelNameRef.current ||
|
|
6320
|
-
isReadingDb) {
|
|
6321
|
-
return;
|
|
6322
|
-
}
|
|
6323
|
-
setIsReadingDb(true);
|
|
6324
|
-
const allItems = yield Item.all(modelNameRef.current);
|
|
6325
|
-
setItems(() => allItems);
|
|
6326
|
-
setIsReadingDb(false);
|
|
6327
|
-
}), [modelName]);
|
|
6328
|
-
useEffect(() => {
|
|
6329
|
-
if (dbsAreReady && !isInitialized) {
|
|
6330
|
-
const _fetchItems = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
6331
|
-
yield readFromDb({ modelName });
|
|
6332
|
-
setIsInitialized(true);
|
|
6333
|
-
});
|
|
6334
|
-
_fetchItems();
|
|
6335
|
-
}
|
|
6336
|
-
}, [dbsAreReady, isInitialized]);
|
|
6337
|
-
useEffect(() => {
|
|
6338
|
-
eventEmitter.addListener('item.requestAll', readFromDb);
|
|
6339
|
-
return () => {
|
|
6340
|
-
eventEmitter.removeListener('item.requestAll');
|
|
6341
|
-
};
|
|
6342
|
-
}, []);
|
|
6343
|
-
return {
|
|
6344
|
-
items: orderBy(items, [
|
|
6345
|
-
(item) => item.lastVersionPublishedAt ||
|
|
6346
|
-
item.attestationCreatedAt ||
|
|
6347
|
-
item.createdAt,
|
|
6348
|
-
], ['desc']).slice(0, 10),
|
|
6349
|
-
isReadingDb,
|
|
6350
|
-
isInitialized,
|
|
6351
|
-
};
|
|
6352
|
-
};
|
|
6353
|
-
const useDbsAreReady = () => {
|
|
6354
|
-
const [dbsAreReady, setDbsAreReady] = useState(false);
|
|
6355
|
-
const update = useCallback(() => {
|
|
6356
|
-
if (dbsAreReady) {
|
|
6357
|
-
return;
|
|
6358
|
-
}
|
|
6359
|
-
setDbsAreReady(true);
|
|
6360
|
-
}, []);
|
|
6361
|
-
useEffect(() => {
|
|
6362
|
-
let globalSubscription;
|
|
6363
|
-
let internalSubscription;
|
|
6364
|
-
const _waitForDbs = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
6365
|
-
const globalService = getGlobalService();
|
|
6366
|
-
const internalService = globalService.getSnapshot().context.internalService;
|
|
6367
|
-
if (!internalService) {
|
|
6368
|
-
logger$1('[useDbsAreReady] [useEffect] no internalService');
|
|
6369
|
-
globalSubscription = globalService.subscribe(({ context }) => {
|
|
6370
|
-
if (!internalSubscription && context && context.internalService) {
|
|
6371
|
-
globalSubscription === null || globalSubscription === void 0 ? void 0 : globalSubscription.unsubscribe();
|
|
6372
|
-
internalSubscription = context.internalService.subscribe((snapshot) => {
|
|
6373
|
-
if (snapshot.value === 'ready') {
|
|
6374
|
-
update();
|
|
6375
|
-
internalSubscription === null || internalSubscription === void 0 ? void 0 : internalSubscription.unsubscribe();
|
|
6497
|
+
[ADDING_MODELS_TO_DB]: {
|
|
6498
|
+
on: {
|
|
6499
|
+
[GLOBAL_ADDING_MODELS_TO_DB_SUCCESS]: {
|
|
6500
|
+
target: INITIALIZED,
|
|
6501
|
+
actions: assign({
|
|
6502
|
+
addedModelRecordsToDb: true,
|
|
6503
|
+
}),
|
|
6504
|
+
},
|
|
6505
|
+
},
|
|
6506
|
+
invoke: {
|
|
6507
|
+
src: 'addModelsToDb',
|
|
6508
|
+
input: ({ context }) => ({ context }),
|
|
6509
|
+
meta: {
|
|
6510
|
+
displayText: 'Adding models to database',
|
|
6511
|
+
},
|
|
6512
|
+
tags: ['loading'],
|
|
6513
|
+
},
|
|
6514
|
+
},
|
|
6515
|
+
[INITIALIZED]: {
|
|
6516
|
+
type: 'parallel',
|
|
6517
|
+
on: {
|
|
6518
|
+
getSeedClass: `.${GETTING_SEED_CLASS}`,
|
|
6519
|
+
getSchemaForModel: `.${GETTING_SCHEMA_FOR_MODEL}`,
|
|
6520
|
+
},
|
|
6521
|
+
meta: {
|
|
6522
|
+
displayText: 'Global service ready',
|
|
6523
|
+
percentComplete: 40,
|
|
6524
|
+
},
|
|
6525
|
+
tags: ['loading'],
|
|
6526
|
+
states: {
|
|
6527
|
+
[GETTING_SEED_CLASS]: {
|
|
6528
|
+
entry: [
|
|
6529
|
+
(_a) => __awaiter(void 0, [_a], void 0, function* ({ context }) {
|
|
6530
|
+
let SeedClass;
|
|
6531
|
+
if (context.environment === 'node') {
|
|
6532
|
+
const { SeedNode } = yield import('./seed-BJtzMyfP.js');
|
|
6533
|
+
SeedClass = SeedNode;
|
|
6376
6534
|
}
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
}
|
|
6407
|
-
}
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
}
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
}
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
const { seedLocalId } = yield createNewItem(Object.assign({ modelName }, itemData));
|
|
6472
|
-
yield Item.find({ modelName, seedLocalId });
|
|
6473
|
-
eventEmitter.emit('item.requestAll', { modelName });
|
|
6474
|
-
setIsCreatingItem(false);
|
|
6475
|
-
}), [isCreatingItem, isReady]);
|
|
6476
|
-
return {
|
|
6477
|
-
createItem,
|
|
6478
|
-
isCreatingItem,
|
|
6479
|
-
};
|
|
6480
|
-
};
|
|
6481
|
-
const useDeleteItem = () => {
|
|
6482
|
-
const [isDeletingItem, setIsDeletingItem] = useState(false);
|
|
6483
|
-
const destroy = useCallback((item) => __awaiter(void 0, void 0, void 0, function* () {
|
|
6484
|
-
if (!item) {
|
|
6485
|
-
return;
|
|
6486
|
-
}
|
|
6487
|
-
setIsDeletingItem(true);
|
|
6488
|
-
const { modelName } = item.getService().getSnapshot().context;
|
|
6489
|
-
yield deleteItem({ seedLocalId: item.seedLocalId });
|
|
6490
|
-
eventEmitter.emit('item.requestAll', { modelName });
|
|
6491
|
-
setIsDeletingItem(false);
|
|
6492
|
-
}), [isDeletingItem]);
|
|
6493
|
-
useEffect(() => { }, []);
|
|
6494
|
-
return {
|
|
6495
|
-
deleteItem: destroy,
|
|
6496
|
-
isDeletingItem,
|
|
6497
|
-
};
|
|
6498
|
-
};
|
|
6499
|
-
const useGlobalServiceStatus = () => {
|
|
6500
|
-
const globalService = getGlobalService();
|
|
6501
|
-
const status = useSelector(globalService, (snapshot) => {
|
|
6502
|
-
return snapshot.value;
|
|
6503
|
-
});
|
|
6504
|
-
const internalStatus = useSelector(globalService.getSnapshot().context.internalService, (snapshot) => {
|
|
6505
|
-
if (!snapshot) {
|
|
6506
|
-
return;
|
|
6507
|
-
}
|
|
6508
|
-
return snapshot.value;
|
|
6509
|
-
});
|
|
6510
|
-
useSelector(globalService, (snapshot) => {
|
|
6511
|
-
return snapshot.context.internalService;
|
|
6512
|
-
});
|
|
6513
|
-
return {
|
|
6514
|
-
status,
|
|
6515
|
-
internalStatus,
|
|
6516
|
-
};
|
|
6517
|
-
};
|
|
6535
|
+
else {
|
|
6536
|
+
const { SeedBrowser } = yield import('./seed-Ch6JPrtQ.js');
|
|
6537
|
+
SeedClass = SeedBrowser;
|
|
6538
|
+
}
|
|
6539
|
+
return SeedClass;
|
|
6540
|
+
}),
|
|
6541
|
+
],
|
|
6542
|
+
meta: {
|
|
6543
|
+
displayText: 'Getting SeedClass',
|
|
6544
|
+
},
|
|
6545
|
+
tags: ['loading'],
|
|
6546
|
+
},
|
|
6547
|
+
[GETTING_SCHEMA_FOR_MODEL]: {
|
|
6548
|
+
invoke: {
|
|
6549
|
+
src: 'getSchemaForModel',
|
|
6550
|
+
input: ({ event, context }) => ({ event, context }),
|
|
6551
|
+
meta: {
|
|
6552
|
+
displayText: 'Getting schema for model',
|
|
6553
|
+
},
|
|
6554
|
+
tags: ['loading'],
|
|
6555
|
+
},
|
|
6556
|
+
},
|
|
6557
|
+
},
|
|
6558
|
+
},
|
|
6559
|
+
},
|
|
6560
|
+
// on: {
|
|
6561
|
+
// '*': {
|
|
6562
|
+
// actions: emit(({ event }) => {
|
|
6563
|
+
// return event
|
|
6564
|
+
// }),
|
|
6565
|
+
// },
|
|
6566
|
+
// },
|
|
6567
|
+
});
|
|
6568
|
+
const globalService = createActor(globalMachine, {
|
|
6569
|
+
input: {},
|
|
6570
|
+
// inspect,
|
|
6571
|
+
inspect: (inspEvent) => {
|
|
6572
|
+
eventEmitter.emit('inspect.globalService', inspEvent);
|
|
6573
|
+
// console.log('[sdk] [service/index] inspEvent', inspEvent)
|
|
6574
|
+
// eventEmitter.emit('globalService', inspEvent)
|
|
6575
|
+
// let eventType: string = inspEvent.type
|
|
6576
|
+
// if (inspEvent.event && inspEvent.event.type) {
|
|
6577
|
+
// eventType = inspEvent.event.type
|
|
6578
|
+
// }
|
|
6579
|
+
//
|
|
6580
|
+
// if (typeof eventType === 'object') {
|
|
6581
|
+
// eventType = JSON.stringify(eventType)
|
|
6582
|
+
// }
|
|
6583
|
+
//
|
|
6584
|
+
// let srcId = inspEvent.actorRef.id
|
|
6585
|
+
//
|
|
6586
|
+
// if (!srcId.includes('seedSdk')) {
|
|
6587
|
+
// srcId = inspEvent.actorRef.logic.config.id
|
|
6588
|
+
// }
|
|
6589
|
+
//
|
|
6590
|
+
// if (inspEvent.type === '@xstate.snapshot') {
|
|
6591
|
+
// if (
|
|
6592
|
+
// inspEvent.event.type === CHILD_SNAPSHOT &&
|
|
6593
|
+
// inspEvent.snapshot &&
|
|
6594
|
+
// inspEvent.snapshot.machine.id === MachineIds.GLOBAL
|
|
6595
|
+
// ) {
|
|
6596
|
+
// return
|
|
6597
|
+
// }
|
|
6598
|
+
// if (inspEvent.snapshot && inspEvent.snapshot.value) {
|
|
6599
|
+
// if (typeof window !== 'undefined') {
|
|
6600
|
+
// eventEmitter.emit('globalService', {
|
|
6601
|
+
// type: eventType,
|
|
6602
|
+
// src: srcId,
|
|
6603
|
+
// snapshot: inspEvent.snapshot,
|
|
6604
|
+
// })
|
|
6605
|
+
// }
|
|
6606
|
+
// }
|
|
6607
|
+
// } else {
|
|
6608
|
+
// if (typeof window !== 'undefined') {
|
|
6609
|
+
// let snapshot
|
|
6610
|
+
//
|
|
6611
|
+
// try {
|
|
6612
|
+
// snapshot = inspEvent.actorRef.getSnapshot()
|
|
6613
|
+
// } catch (e) {
|
|
6614
|
+
// // This fails if the actor hasn't initialized yet, but that's OK I think
|
|
6615
|
+
// // console.log('[sdk] [service/index] ERROR', e)
|
|
6616
|
+
// }
|
|
6617
|
+
//
|
|
6618
|
+
// eventEmitter.emit('globalService', {
|
|
6619
|
+
// type: eventType,
|
|
6620
|
+
// src: srcId,
|
|
6621
|
+
// snapshot,
|
|
6622
|
+
// })
|
|
6623
|
+
// }
|
|
6624
|
+
// }
|
|
6625
|
+
},
|
|
6626
|
+
});
|
|
6627
|
+
globalService.start();
|
|
6628
|
+
const getGlobalService = () => globalService;
|
|
6518
6629
|
|
|
6519
6630
|
const logger = debug('app:services:events');
|
|
6520
6631
|
const handleServiceSaveState = (event) => {
|
|
@@ -6526,5 +6637,5 @@ const setupServicesEventHandlers = () => {
|
|
|
6526
6637
|
eventEmitter.addListener('service.saveState.request', handleServiceSaveState);
|
|
6527
6638
|
};
|
|
6528
6639
|
|
|
6529
|
-
export { useDeleteItem as $, APP_DB_CONFIG as A, setupFsListeners as B, CHILD_SNAPSHOT as C, DB_NAME_SDK_CONFIG as D, setupAllItemsEventHandlers as E, setupServicesEventHandlers as F, GET_SCHEMAS as G, globalService as H, Item as I, Json as J, getModel as K, List as L, Model as M, getModels as N, getModelNames as O, Property as P, areFsListenersReady as Q, Relation as R, SCHEMA_NJK as S, Text as T, ItemProperty as U, useItems as V, useItem as W, useItemProperties as X, useCreateItem as Y, useItemProperty as Z, __awaiter as _, GET_SEEDS as a,
|
|
6530
|
-
//# sourceMappingURL=events-
|
|
6640
|
+
export { useDeleteItem as $, APP_DB_CONFIG as A, setupFsListeners as B, CHILD_SNAPSHOT as C, DB_NAME_SDK_CONFIG as D, setupAllItemsEventHandlers as E, setupServicesEventHandlers as F, GET_SCHEMAS as G, globalService as H, Item as I, Json as J, getModel as K, List as L, Model as M, getModels as N, getModelNames as O, Property as P, areFsListenersReady as Q, Relation as R, SCHEMA_NJK as S, Text as T, ItemProperty as U, useItems as V, useItem as W, useItemProperties as X, useCreateItem as Y, useItemProperty as Z, __awaiter as _, GET_SEEDS as a, useServices as a0, getGlobalService as a1, getCorrectId as a2, GET_SEED_IDS as b, GET_STORAGE_TRANSACTION_ID as c, GET_VERSIONS as d, GET_PROPERTIES as e, GET_ALL_PROPERTIES_FOR_ALL_VERSIONS as f, itemMachineAll as g, internalMachine as h, itemMachineSingle as i, isNode as j, isBrowser as k, isReactNative as l, __decorate as m, __metadata as n, models as o, SCHEMA_TS as p, SDK_DB_CONFIG as q, SEED_DB_CONFIG as r, addModelsToInternalDb as s, ImageSrc as t, createNewMetadataFromExistingRecord as u, generateId as v, eventEmitter as w, getDb as x, DB_NAME_APP as y, setModel as z };
|
|
6641
|
+
//# sourceMappingURL=events-DY-qRoqO.js.map
|