@seedprotocol/sdk 0.1.46 → 0.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/dist/bin.js.map +1 -1
  2. package/dist/constants-BLctWkrn.js.map +1 -1
  3. package/dist/{index-BEzB8REh.js → index-DMIKRod-.js} +3684 -3660
  4. package/dist/index-DMIKRod-.js.map +1 -0
  5. package/dist/{index-ChGsdGPJ.js → index-wKss7188.js} +10 -10
  6. package/dist/index-wKss7188.js.map +1 -0
  7. package/dist/main.js +7 -7
  8. package/dist/{seed.schema.config-jKpK-lR6.js → seed.schema.config-C0M8Rcti.js} +7 -7
  9. package/dist/seed.schema.config-C0M8Rcti.js.map +1 -0
  10. package/dist/src/AppStateSchema.ts +10 -0
  11. package/dist/src/Attestation.ts +21 -0
  12. package/dist/src/ConfigSchema.ts +15 -0
  13. package/dist/src/ItemProperty.ts +383 -0
  14. package/dist/src/MetadataSchema.ts +28 -0
  15. package/dist/src/ModelSchema.ts +46 -0
  16. package/dist/src/ModelUidSchema.ts +16 -0
  17. package/dist/src/PropertyUidSchema.ts +16 -0
  18. package/dist/src/Schema.ts +17 -0
  19. package/dist/src/SeedSchema.ts +29 -0
  20. package/dist/src/VersionSchema.ts +16 -0
  21. package/dist/src/actors.ts +10 -0
  22. package/dist/src/addModelsToDb.ts +150 -0
  23. package/dist/src/allItems.ts +23 -0
  24. package/dist/src/arweave.ts +37 -0
  25. package/dist/src/browser.app.db.config.ts +27 -0
  26. package/dist/src/browser.seed.db.config.ts +33 -0
  27. package/dist/src/browser.ts +30 -0
  28. package/dist/src/checkStatus.ts +50 -0
  29. package/dist/src/client.ts +85 -0
  30. package/dist/src/configureFs.ts +81 -0
  31. package/dist/src/connectToDb.ts +74 -0
  32. package/dist/src/connectionManager.ts +67 -0
  33. package/dist/src/constants.ts +118 -0
  34. package/dist/src/create.ts +39 -0
  35. package/dist/src/createItem.ts +15 -0
  36. package/dist/src/createItemMachine.ts +37 -0
  37. package/dist/src/createPublishAttempt.ts +16 -0
  38. package/dist/src/createSeeds.ts +24 -0
  39. package/dist/src/createVersion.ts +33 -0
  40. package/dist/src/db.ts +247 -0
  41. package/dist/src/dbMachine.ts +181 -0
  42. package/dist/src/deleteItem.ts +19 -0
  43. package/dist/src/download.ts +289 -0
  44. package/dist/src/drizzle.ts +82 -0
  45. package/dist/src/environment.ts +15 -0
  46. package/dist/src/eventBus.ts +5 -0
  47. package/dist/src/events.ts +14 -0
  48. package/dist/src/fetchDataFromEas.ts +90 -0
  49. package/dist/src/fetchDbData.ts +16 -0
  50. package/dist/src/fetchRelatedItems.ts +179 -0
  51. package/dist/src/fetchSeeds.ts +44 -0
  52. package/dist/src/fetchVersions.ts +41 -0
  53. package/dist/src/files.ts +16 -0
  54. package/dist/src/fragment-masking.ts +87 -0
  55. package/dist/src/fsProxy.ts +36 -0
  56. package/dist/src/getItem.ts +189 -0
  57. package/dist/src/getItemProperties.ts +162 -0
  58. package/dist/src/getItems.ts +75 -0
  59. package/dist/src/getMetadata.ts +40 -0
  60. package/dist/src/getModelSchemas.ts +88 -0
  61. package/dist/src/getSchemaForModel.ts +42 -0
  62. package/dist/src/getSeedData.ts +34 -0
  63. package/dist/src/getVersionData.ts +58 -0
  64. package/dist/src/getVersionsForVersionUids.ts +39 -0
  65. package/dist/src/globalMachine.ts +259 -0
  66. package/dist/src/gql.ts +113 -0
  67. package/dist/src/graphql.ts +3201 -0
  68. package/dist/src/helpers.ts +150 -0
  69. package/dist/src/hydrateExistingItem.ts +137 -0
  70. package/dist/src/hydrateFromDb.ts +254 -0
  71. package/dist/src/hydrateNewItem.ts +34 -0
  72. package/dist/src/index.d.ts +5 -0
  73. package/dist/src/index.ts +21 -0
  74. package/dist/src/init.ts +61 -0
  75. package/dist/src/initialize.ts +127 -0
  76. package/dist/src/internalMachine.ts +220 -0
  77. package/dist/src/item.ts +324 -0
  78. package/dist/src/itemMachineAll.ts +158 -0
  79. package/dist/src/itemMachineSingle.ts +175 -0
  80. package/dist/src/loadAppDb.ts +47 -0
  81. package/dist/src/logger.ts +33 -0
  82. package/dist/src/machine.ts +55 -0
  83. package/dist/src/machines.ts +58 -0
  84. package/dist/src/migrate.ts +288 -0
  85. package/dist/src/model.ts +71 -0
  86. package/dist/src/modelClass.ts +19 -0
  87. package/dist/src/node.app.db.config.ts +40 -0
  88. package/dist/src/prepareDb.ts +34 -0
  89. package/dist/src/preparePublishRequestData.ts +81 -0
  90. package/dist/src/processItems.ts +71 -0
  91. package/dist/src/property.ts +161 -0
  92. package/dist/src/propertyMachine.ts +154 -0
  93. package/dist/src/publish.ts +31 -0
  94. package/dist/src/publishMachine.ts +77 -0
  95. package/dist/src/queries.ts +13 -0
  96. package/dist/src/read.ts +174 -0
  97. package/dist/src/recoverDeletedItem.ts +14 -0
  98. package/dist/src/request.ts +54 -0
  99. package/dist/src/requestAll.ts +157 -0
  100. package/dist/src/resolveRelatedValue.ts +348 -0
  101. package/dist/src/resolveRemoteStorage.ts +87 -0
  102. package/dist/src/save.ts +183 -0
  103. package/dist/src/saveConfig.ts +79 -0
  104. package/dist/src/saveDataToDb.ts +145 -0
  105. package/dist/src/saveMetadata.ts +18 -0
  106. package/dist/src/saveValueToDb.ts +94 -0
  107. package/dist/src/seed.schema.config.ts +25 -0
  108. package/dist/src/seed.ts +37 -0
  109. package/dist/src/seedData.ts +0 -0
  110. package/dist/src/seedProtocol.ts +17 -0
  111. package/dist/src/services.ts +359 -0
  112. package/dist/src/sqlWasmClient.ts +88 -0
  113. package/dist/src/syncDbWithEas.ts +686 -0
  114. package/dist/src/trash.ts +29 -0
  115. package/dist/src/ts-to-proto.ts +101 -0
  116. package/dist/src/types.ts +12 -0
  117. package/dist/src/upload.ts +86 -0
  118. package/dist/src/validate.ts +42 -0
  119. package/dist/src/validateInput.ts +33 -0
  120. package/dist/src/validateItemData.ts +20 -0
  121. package/dist/src/waitForDb.ts +23 -0
  122. package/dist/src/wasm.d.ts +8300 -0
  123. package/dist/src/write.ts +366 -0
  124. package/dist/types/src/browser/db/read/getModelSchemas.d.ts.map +1 -1
  125. package/dist/types/src/browser/events/item/create.d.ts.map +1 -1
  126. package/dist/types/src/browser/events/item/publish.d.ts.map +1 -1
  127. package/dist/types/src/browser/events/item/requestAll.d.ts.map +1 -1
  128. package/dist/types/src/browser/events/item/syncDbWithEas.d.ts.map +1 -1
  129. package/dist/types/src/browser/item/single/actors/hydrateExistingItem.d.ts +3 -1
  130. package/dist/types/src/browser/item/single/actors/hydrateExistingItem.d.ts.map +1 -1
  131. package/dist/types/src/browser/item/single/actors/saveDataToDb.d.ts +3 -3
  132. package/dist/types/src/browser/item/single/itemMachineSingle.d.ts +3 -3
  133. package/dist/types/src/browser/property/ItemProperty.d.ts +7 -7
  134. package/dist/types/src/browser/property/ItemProperty.d.ts.map +1 -1
  135. package/dist/types/src/browser/property/actors/hydrateFromDb.d.ts.map +1 -1
  136. package/dist/types/src/browser/property/actors/initialize.d.ts.map +1 -1
  137. package/dist/types/src/browser/property/actors/resolveRemoteStorage.d.ts +3 -3
  138. package/dist/types/src/browser/react/trash.d.ts +1 -1
  139. package/dist/types/src/browser/react/trash.d.ts.map +1 -1
  140. package/dist/types/src/browser/services/db/dbMachine.d.ts +6 -6
  141. package/dist/types/src/browser/services/publish/publishMachine.d.ts +17 -17
  142. package/dist/types/src/types/machines.d.ts +4 -0
  143. package/dist/types/src/types/machines.d.ts.map +1 -1
  144. package/package.json +1 -1
  145. package/dist/index-BEzB8REh.js.map +0 -1
  146. package/dist/index-ChGsdGPJ.js.map +0 -1
  147. package/dist/seed.schema.config-jKpK-lR6.js.map +0 -1
@@ -0,0 +1,29 @@
1
+ import { int, sqliteTable, text } from 'drizzle-orm/sqlite-core'
2
+
3
+ export const seeds = sqliteTable(
4
+ 'seeds',
5
+ {
6
+ localId: text('local_id').unique(),
7
+ uid: text('uid'),
8
+ schemaUid: text('schema_uid'),
9
+ type: text('type'),
10
+ attestationRaw: text('attestation_raw'),
11
+ attestationCreatedAt: int('attestation_created_at'),
12
+ createdAt: int('created_at'),
13
+ updatedAt: int('updated_at'),
14
+ _markedForDeletion: int('_marked_for_deletion'),
15
+ },
16
+ // {
17
+ // triggers: [
18
+ // sql<string>`CREATE TRIGGER IF NOT EXISTS seeds_created_at_trigger
19
+ // BEFORE INSERT
20
+ // ON seeds
21
+ // FOR EACH ROW
22
+ // BEGIN
23
+ // SELECT strftime('%s', 'now') * 1000 INTO NEW.created_at;
24
+ // END;`,
25
+ // ],
26
+ // },
27
+ )
28
+
29
+ export type SeedType = seeds.$inferSelect
@@ -0,0 +1,16 @@
1
+ import { int, sqliteTable, text } from 'drizzle-orm/sqlite-core'
2
+
3
+ export const versions = sqliteTable('versions', {
4
+ localId: text('local_id').unique(),
5
+ uid: text('uid'),
6
+ seedLocalId: text('seed_local_id'),
7
+ seedUid: text('seed_uid'),
8
+ seedType: text('seed_type'),
9
+ note: text('note'),
10
+ createdAt: int('created_at'),
11
+ updatedAt: int('updated_at'),
12
+ attestationCreatedAt: int('attestation_created_at'),
13
+ attestationRaw: text('attestation_raw'),
14
+ })
15
+
16
+ export type VersionsType = versions.$inferSelect
@@ -0,0 +1,10 @@
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { uploadMachine } from '@/browser/schema/file/upload/index'
3
+
4
+ export const uploadBinaryData = fromCallback<EventObject, typeof uploadMachine>(
5
+ ({ sendBack, receive, input }) => {},
6
+ )
7
+
8
+ export const uploadMetadata = fromCallback<EventObject, typeof uploadMachine>(
9
+ ({ sendBack, receive, input }) => {},
10
+ )
@@ -0,0 +1,150 @@
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { models as modelsTable, modelUids } from '@/shared/seedSchema'
3
+ import { eq } from 'drizzle-orm'
4
+ import { toSnakeCase } from '@/shared/helpers'
5
+ import { easClient, queryClient } from '@/browser/helpers'
6
+ import { getAppDb } from '@/browser/db/sqlWasmClient'
7
+ import { GLOBAL_ADDING_MODELS_TO_DB_SUCCESS } from '@/browser/services/internal/constants'
8
+ import { eventEmitter } from '@/eventBus'
9
+ import { FromCallbackInput, GlobalMachineContext } from '@/types'
10
+ import debug from 'debug'
11
+ import { GET_SCHEMAS } from '@/browser/item/queries'
12
+
13
+ const logger = debug('app:services:global:actors:addModelsToDb')
14
+
15
+ export const addModelsToDb = fromCallback<
16
+ EventObject,
17
+ FromCallbackInput<GlobalMachineContext>
18
+ >(({ sendBack, input: { context } }) => {
19
+ const { models } = context
20
+
21
+ const _addModelsToDb = async () => {
22
+ const appDb = getAppDb()
23
+
24
+ if (!models) {
25
+ return
26
+ }
27
+
28
+ const { models: SeedModels } = await import(
29
+ '@/shared/configs/seed.schema.config'
30
+ )
31
+
32
+ const allModels = {
33
+ ...SeedModels,
34
+ ...models,
35
+ }
36
+
37
+ let hasModelsInDb = false
38
+ const schemaDefsByModelName = new Map<
39
+ string,
40
+ {
41
+ dbId: number
42
+ schemaDef: string
43
+ }
44
+ >()
45
+
46
+ for (const [modelName, _] of Object.entries(allModels)) {
47
+ logger(
48
+ '[helpers/db] [addModelsToInternalDb] starting modelName:',
49
+ modelName,
50
+ )
51
+
52
+ let foundModel
53
+
54
+ const foundModelsQuery = await appDb
55
+ .select()
56
+ .from(modelsTable)
57
+ .where(eq(modelsTable.name, modelName))
58
+
59
+ if (!foundModelsQuery || foundModelsQuery.length === 0) {
60
+ await appDb.insert(modelsTable).values({
61
+ name: modelName,
62
+ })
63
+
64
+ logger('[global/actors] [addModelsToDb] inserted model:', modelName)
65
+ const foundModels = await appDb
66
+ .select({
67
+ id: modelsTable.id,
68
+ name: modelsTable.name,
69
+ uid: modelUids.uid,
70
+ })
71
+ .from(modelsTable)
72
+ .leftJoin(modelUids, eq(modelsTable.id, modelUids.modelId))
73
+ .where(eq(modelsTable.name, modelName))
74
+ .limit(1)
75
+
76
+ foundModel = foundModels[0]
77
+ }
78
+
79
+ if (foundModelsQuery && foundModelsQuery.length > 0) {
80
+ foundModel = foundModelsQuery[0]
81
+ }
82
+
83
+ if (!foundModel) {
84
+ hasModelsInDb = false
85
+ break
86
+ }
87
+
88
+ schemaDefsByModelName.set(modelName, {
89
+ dbId: foundModel.id,
90
+ schemaDef: `bytes32 ${toSnakeCase(modelName)}`,
91
+ })
92
+ }
93
+
94
+ if (!hasModelsInDb) {
95
+ return false
96
+ }
97
+
98
+ const schemaDefs = Array.from(schemaDefsByModelName.values()).map(
99
+ ({ schemaDef }) => schemaDef,
100
+ )
101
+
102
+ const { schemas } = await queryClient.fetchQuery({
103
+ queryKey: [`getSchemasVersion`],
104
+ queryFn: async () =>
105
+ easClient.request(GET_SCHEMAS, {
106
+ where: {
107
+ schema: {
108
+ in: schemaDefs,
109
+ },
110
+ },
111
+ }),
112
+ })
113
+
114
+ if (!schemas || schemas.length === 0) {
115
+ throw new Error(`No schemas found`)
116
+ }
117
+
118
+ for (const schema of schemas) {
119
+ const modelId = Array.from(schemaDefsByModelName.values()).find(
120
+ ({ schemaDef }) => schemaDef === schema.schema,
121
+ )?.dbId
122
+
123
+ if (!modelId) {
124
+ throw new Error(`No modelId found for schema ${schema.schema}`)
125
+ }
126
+
127
+ await appDb
128
+ .insert(modelUids)
129
+ .values({
130
+ modelId,
131
+ uid: schema.id,
132
+ })
133
+ .onConflictDoNothing()
134
+ }
135
+ }
136
+
137
+ _addModelsToDb().then((hasModelsInDb) => {
138
+ sendBack({ type: GLOBAL_ADDING_MODELS_TO_DB_SUCCESS })
139
+ if (hasModelsInDb) {
140
+ }
141
+ for (const [modelName, model] of Object.entries(models)) {
142
+ const service = context[`${modelName}Service`]
143
+ service.send({ type: 'modelsFound' })
144
+ }
145
+ eventEmitter.emit('syncDbWithEas')
146
+ return
147
+ })
148
+
149
+ return () => {}
150
+ })
@@ -0,0 +1,23 @@
1
+ import { getGlobalService } from '@/browser/services/global'
2
+ import { writeAppState } from '@/browser/db/write'
3
+
4
+ type SaveServiceEvent = {
5
+ modelName: string
6
+ }
7
+
8
+ export const saveServiceHandler = async (event: SaveServiceEvent) => {
9
+ const globalService = getGlobalService()
10
+
11
+ if (!globalService) {
12
+ return
13
+ }
14
+
15
+ const { modelName } = event
16
+
17
+ const service = globalService.getSnapshot().context[`${modelName}Service`]
18
+
19
+ await writeAppState(
20
+ `snapshot__${modelName}`,
21
+ JSON.stringify(service.getPersistedSnapshot()),
22
+ )
23
+ }
@@ -0,0 +1,37 @@
1
+ import Arweave from 'arweave'
2
+
3
+ export const getArweave = (): Arweave | undefined => {
4
+ if (
5
+ typeof window === 'undefined' ||
6
+ !Arweave ||
7
+ (!Object.keys(Arweave).includes('init') &&
8
+ !Object.keys(Arweave).includes('default'))
9
+ ) {
10
+ return
11
+ }
12
+
13
+ if (process.env.NODE_ENV === 'production') {
14
+ return Arweave.init({
15
+ host: process.env.NEXT_PUBLIC_ARWEAVE_HOST,
16
+ protocol: 'https',
17
+ })
18
+ }
19
+
20
+ // return Arweave.init({
21
+ // host : 'localhost',
22
+ // port : 1984,
23
+ // protocol : 'http',
24
+ // },)
25
+
26
+ if (Object.keys(Arweave).includes('default')) {
27
+ return Arweave.default.init({
28
+ host: 'permagate.io',
29
+ protocol: 'https',
30
+ })
31
+ }
32
+
33
+ return Arweave.init({
34
+ host: 'permagate.io',
35
+ protocol: 'https',
36
+ })
37
+ }
@@ -0,0 +1,27 @@
1
+ import { defineConfig } from 'drizzle-kit'
2
+ import dotenv from 'dotenv'
3
+ import process from 'node:process'
4
+ import path from 'path'
5
+
6
+ dotenv.config()
7
+
8
+ let dotSeedDir = path.join(process.cwd(), '.seed')
9
+
10
+ if (process.env.IS_SEED_DEV) {
11
+ dotSeedDir = path.join(
12
+ process.cwd(),
13
+ '__tests__',
14
+ '__mocks__',
15
+ 'project',
16
+ '.seed',
17
+ )
18
+ }
19
+
20
+ export default defineConfig({
21
+ schema: [`${dotSeedDir}/app/schema/*Schema.ts`],
22
+ dialect: 'sqlite',
23
+ out: `${dotSeedDir}/app/db`,
24
+ dbCredentials: {
25
+ url: `${dotSeedDir}/app/db/app_db.sqlite3`,
26
+ },
27
+ })
@@ -0,0 +1,33 @@
1
+ import { defineConfig } from 'drizzle-kit'
2
+ import dotenv from 'dotenv'
3
+ import process from 'node:process'
4
+ import path from 'path'
5
+
6
+ dotenv.config()
7
+
8
+ let sdkRoot = './node_modules/@seedprotocol/sdk'
9
+
10
+ if (process.env.IS_SEED_DEV) {
11
+ sdkRoot = './src'
12
+ }
13
+
14
+ let dotSeedDir = path.join(process.cwd(), '.seed')
15
+
16
+ if (process.env.IS_SEED_DEV) {
17
+ dotSeedDir = path.join(
18
+ process.cwd(),
19
+ '__tests__',
20
+ '__mocks__',
21
+ 'project',
22
+ '.seed',
23
+ )
24
+ }
25
+
26
+ export default defineConfig({
27
+ schema: `${sdkRoot}/browser/db/seedSchema/*Schema.ts`,
28
+ dialect: 'sqlite',
29
+ out: `${dotSeedDir}/seed/db`,
30
+ dbCredentials: {
31
+ url: `${dotSeedDir}/seed/db/seed_db.sqlite3`,
32
+ },
33
+ })
@@ -0,0 +1,30 @@
1
+ import { Endpoints } from './index'
2
+ import { SqliteRemoteResult } from 'drizzle-orm/sqlite-proxy'
3
+
4
+ export type SeedInitBrowserProps = {
5
+ endpoints: Endpoints
6
+ }
7
+
8
+ export interface SeedInitBrowser {
9
+ (props: SeedInitBrowserProps): Promise<void>
10
+ }
11
+
12
+ export type DbQueryResult = SqliteRemoteResult<SqliteWasmResult>
13
+
14
+ export type ResultObject = {
15
+ [key: string]: string
16
+ }
17
+
18
+ export type SqliteWasmResult = {
19
+ type: string | null
20
+ row: string[] | null
21
+ rowNumber: number | null
22
+ columnNames: string[]
23
+ }
24
+
25
+ export type SqliteWasmCallback = (result: SqliteWasmResult) => void
26
+
27
+ export type ReturnObj = {
28
+ database: string
29
+ [key: string]: string | number | null | undefined | string[]
30
+ }
@@ -0,0 +1,50 @@
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { DbServiceContext, FromCallbackInput } from '@/types'
3
+ import {
4
+ BROWSER_FS_TOP_DIR,
5
+ DB_CHECK_STATUS_EXISTS,
6
+ DB_CHECK_STATUS_UPDATE_PATHS,
7
+ } from '@/browser/services/internal/constants'
8
+ import debug from 'debug'
9
+
10
+ const logger = debug('app:services:db:actors:checkStatus')
11
+
12
+ export const checkStatus = fromCallback<
13
+ EventObject,
14
+ FromCallbackInput<DbServiceContext>
15
+ >(({ sendBack, input: { context } }) => {
16
+ const { dbName } = context
17
+
18
+ logger('[db/actors] checkStatus context', context)
19
+ const pathToDir = `${BROWSER_FS_TOP_DIR}`
20
+ const pathToDbDir = `${pathToDir}/db`
21
+ const pathToDb = `${pathToDbDir}/${dbName}.sqlite3`
22
+
23
+ sendBack({
24
+ type: DB_CHECK_STATUS_UPDATE_PATHS,
25
+ pathToDb,
26
+ pathToDir,
27
+ pathToDbDir,
28
+ })
29
+
30
+ const _checkStatus = async (): Promise<void> => {
31
+ // logger('[db/actors] _checkStatus pathToDb', pathToDb)
32
+ // const exists = await fs.promises.exists(pathToJournal)
33
+ // if (exists) {
34
+ // sendBack({
35
+ // type: DB_CHECK_STATUS_EXISTS,
36
+ // })
37
+ // return
38
+ // }
39
+ //
40
+ // return new Promise((resolve) => {
41
+ // sendBack({ type: DB_CHECK_STATUS_DOES_NOT_EXIST })
42
+ //
43
+ // })
44
+ }
45
+
46
+ _checkStatus().then(() => {
47
+ sendBack({ type: DB_CHECK_STATUS_EXISTS })
48
+ return
49
+ })
50
+ })
@@ -0,0 +1,85 @@
1
+ import { areFsListenersReady, setupFsListeners } from '@/browser/events/files'
2
+ import { setupAllItemsEventHandlers } from '@/browser/events'
3
+ import { setupServicesEventHandlers } from '@/browser/services/events'
4
+ import { eventEmitter } from '@/eventBus'
5
+ import { globalService } from '@/browser/services'
6
+ import { ModelClassType, SeedConstructorOptions } from '@/types'
7
+ import {
8
+ getModel,
9
+ getModelNames,
10
+ getModels,
11
+ setModel,
12
+ } from '@/browser/stores/modelClass'
13
+ import { setupServiceHandlers } from '@/browser/events/services'
14
+
15
+ const client = {
16
+ init: ({ config, addresses }: SeedConstructorOptions) => {
17
+ const { endpoints, models } = config
18
+
19
+ for (const [key, value] of Object.entries(models)) {
20
+ setModel(key, value)
21
+ }
22
+ setupFsListeners()
23
+ setupAllItemsEventHandlers()
24
+ setupServicesEventHandlers()
25
+ setupServiceHandlers()
26
+ if (areFsListenersReady()) {
27
+ eventEmitter.emit('fs.init')
28
+ }
29
+ if (!areFsListenersReady()) {
30
+ console.error('fs listeners not ready during init')
31
+ }
32
+ globalService.send({ type: 'init', endpoints, models, addresses })
33
+ import('@/shared/configs/seed.schema.config').then(({ models }) => {
34
+ for (const [key, value] of Object.entries(models)) {
35
+ setModel(key, value)
36
+ }
37
+ })
38
+ },
39
+ subscribe: (callback: any) => {
40
+ callback({
41
+ type: '@xstate.snapshot',
42
+ actorRef: globalService,
43
+ snapshot: globalService.getSnapshot(),
44
+ })
45
+ eventEmitter.addListener('globalService', callback)
46
+
47
+ return {
48
+ unsubscribe: () => {
49
+ eventEmitter.removeListener('globalService', callback)
50
+ },
51
+ }
52
+ },
53
+ on: (outerEvent: string, callback: any) => {
54
+ eventEmitter.addListener(outerEvent, callback)
55
+
56
+ return {
57
+ unsubscribe: () => {
58
+ eventEmitter.removeListener(outerEvent, callback)
59
+ },
60
+ }
61
+ },
62
+ getSeedClass: async () => {
63
+ return new Promise((resolve) => {
64
+ const subscription = globalService.subscribe((snapshot) => {
65
+ if (snapshot.status === 'done') {
66
+ resolve(snapshot.output)
67
+ }
68
+ })
69
+
70
+ globalService.send({ type: 'getSeed' })
71
+ subscription.unsubscribe()
72
+ })
73
+ },
74
+ getModel: (modelName: string) => {
75
+ return getModel(modelName)
76
+ },
77
+ getModels: (): Record<string, ModelClassType> => {
78
+ return getModels()
79
+ },
80
+ getModelNames: (): string[] => {
81
+ return getModelNames()
82
+ },
83
+ }
84
+
85
+ export { client }
@@ -0,0 +1,81 @@
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { areFsListenersReady, isFsInitialized } from '@/browser/events/files'
3
+ import { waitForEvent } from '@/browser/events'
4
+ import {
5
+ BROWSER_FS_TOP_DIR,
6
+ DB_WAITING_FOR_FILES_RECEIVED,
7
+ INTERNAL_CONFIGURING_FS_SUCCESS,
8
+ } from '@/browser/services/internal/constants'
9
+ import { fs } from '@zenfs/core'
10
+ import debug from 'debug'
11
+ import { FromCallbackInput, InternalMachineContext } from '@/types'
12
+
13
+ const logger = debug('app:internal:actors:configureFs')
14
+
15
+ export const configureFs = fromCallback<
16
+ EventObject,
17
+ FromCallbackInput<InternalMachineContext>
18
+ >(({ sendBack, input: { context } }) => {
19
+ const { endpoints, appDbService } = context
20
+
21
+ logger('[internal/actors] [configureFs] Configuring FS')
22
+
23
+ const _configureFs = async (): Promise<void> => {
24
+ logger('[internal/actors] [configureFs] calling _configureFs')
25
+
26
+ logger(
27
+ '[internal/actors] [configureFs] areFsListenersReady:',
28
+ areFsListenersReady(),
29
+ )
30
+ logger(
31
+ '[internal/actors] [configureFs] isFsInitialized:',
32
+ isFsInitialized(),
33
+ )
34
+
35
+ await waitForEvent({
36
+ req: {
37
+ eventLabel: 'fs.downloadAll.request',
38
+ data: { endpoints },
39
+ },
40
+ res: {
41
+ eventLabel: 'fs.downloadAll.success',
42
+ },
43
+ })
44
+
45
+ const journalPath = `${BROWSER_FS_TOP_DIR}/db/meta/_journal.json`
46
+
47
+ const journalExists = await fs.promises.exists(journalPath)
48
+
49
+ if (journalExists) {
50
+ appDbService.send({ type: DB_WAITING_FOR_FILES_RECEIVED })
51
+ }
52
+
53
+ // return new Promise<void>((resolve) => {
54
+ // const interval = setInterval(() => {
55
+ // journalExistsSync = fs.existsSync(journalPath)
56
+ // logger(
57
+ // '[internal/actors] [configureFs] journalExistsSync:',
58
+ // journalExistsSync,
59
+ // )
60
+ // if (journalExistsSync) {
61
+ // service.send({ type: DB_WAITING_FOR_FILES_RECEIVED })
62
+ // clearInterval(interval)
63
+ // resolve()
64
+ // }
65
+ // }, 200)
66
+ // })
67
+
68
+ logger('[internal/actors] [configureFs] fs configured!')
69
+ }
70
+
71
+ // Some of our dependencies use fs sync functions, which don't work with
72
+ // OPFS. ZenFS creates an async cache of all files so that the sync functions
73
+ // work, but we have to wait for it to be built. Otherwise things like
74
+ // drizzleMigrate will fail since they can't see the migration files yet.
75
+ _configureFs().then(() => {
76
+ sendBack({ type: INTERNAL_CONFIGURING_FS_SUCCESS })
77
+ return
78
+ })
79
+
80
+ return () => {}
81
+ })
@@ -0,0 +1,74 @@
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { DbServiceContext, FromCallbackInput } from '@/types'
3
+ import { getSqliteWasmClient } from '@/browser/db/sqlWasmClient'
4
+ import { DB_CREATING_SUCCESS } from '@/browser/services/internal/constants'
5
+ import debug from 'debug'
6
+
7
+ const logger = debug('app:services:db:actors:connectToDb')
8
+
9
+ export const connectToDb = fromCallback<
10
+ EventObject,
11
+ FromCallbackInput<DbServiceContext>
12
+ >(({ sendBack, input: { context } }) => {
13
+ logger('[db/actors] connectToDb context', context)
14
+
15
+ const { dbName, pathToDir } = context
16
+
17
+ let isConnecting = false
18
+ let dbId: string | undefined
19
+
20
+ const _create = async (): Promise<void> => {
21
+ if (isConnecting) {
22
+ return
23
+ }
24
+ isConnecting = true
25
+ let response
26
+
27
+ const sqliteWasmClient = await getSqliteWasmClient()
28
+
29
+ //@ts-ignore
30
+ response = await sqliteWasmClient('config-get', {})
31
+ logger(response)
32
+ logger('Running SQLite3 version', response.result.version.libVersion)
33
+
34
+ //@ts-ignore
35
+ response = await sqliteWasmClient('open', {
36
+ filename: `file:${pathToDir}/db/${dbName}.sqlite3?vfs=opfs`,
37
+ })
38
+
39
+ logger(response)
40
+ dbId = response.dbId
41
+ // logger(`dbId: ${dbId}`)
42
+ logger(
43
+ 'OPFS is available, created persisted database at',
44
+ response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'),
45
+ )
46
+ }
47
+
48
+ const interval = setInterval(() => {
49
+ // TODO: Add a timeout
50
+ // TODO: Add a cancel token to the promise so we can prevent more loops starting while we're checking the successful outcome
51
+ if (dbId) {
52
+ // logger(
53
+ // '[db/actors] opening sqliteWasm connection with dbId:',
54
+ // dbId,
55
+ // )
56
+ clearInterval(interval)
57
+ sendBack({ type: DB_CREATING_SUCCESS, dbId })
58
+ return
59
+ }
60
+ _create()
61
+ .then(() => {
62
+ return
63
+ })
64
+ .catch((e) => {
65
+ isConnecting = false
66
+ })
67
+ }, 500)
68
+
69
+ return () => {
70
+ if (interval) {
71
+ clearInterval(interval)
72
+ }
73
+ }
74
+ })