@seedprotocol/sdk 0.3.0 → 0.3.1

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 (200) hide show
  1. package/dist/{ArweaveClient-CmJYeuq1.js → ArweaveClient-C0g0es2v.js} +2 -2
  2. package/dist/{ArweaveClient-EXXrXUzz.js.map → ArweaveClient-C0g0es2v.js.map} +1 -1
  3. package/dist/{ArweaveClient-EXXrXUzz.js → ArweaveClient-CzkBgiZY.js} +2 -2
  4. package/dist/{ArweaveClient-CmJYeuq1.js.map → ArweaveClient-CzkBgiZY.js.map} +1 -1
  5. package/dist/{Db-CESKJH-G.js → Db-C4oog-0n.js} +3 -3
  6. package/dist/{Db-CESKJH-G.js.map → Db-C4oog-0n.js.map} +1 -1
  7. package/dist/{Db-DiTPSbQ8.js → Db-VPouegkr.js} +3 -3
  8. package/dist/{Db-DiTPSbQ8.js.map → Db-VPouegkr.js.map} +1 -1
  9. package/dist/{EasClient-BesHK2bO.js → EasClient-B9a3NsTi.js} +2 -2
  10. package/dist/{EasClient-BesHK2bO.js.map → EasClient-B9a3NsTi.js.map} +1 -1
  11. package/dist/{EasClient-Cop6WtWl.js → EasClient-DQ93i2ci.js} +2 -2
  12. package/dist/{EasClient-Cop6WtWl.js.map → EasClient-DQ93i2ci.js.map} +1 -1
  13. package/dist/{FileManager-DTzkncLh.js → FileManager-_ErxVuwb.js} +8 -5
  14. package/dist/FileManager-_ErxVuwb.js.map +1 -0
  15. package/dist/{Item-B5Tz-Y7t.js → Item-D9HFPxsK.js} +3 -3
  16. package/dist/{Item-B5Tz-Y7t.js.map → Item-D9HFPxsK.js.map} +1 -1
  17. package/dist/{ItemProperty-DBV0Iib_.js → ItemProperty-BdtvKrEy.js} +3 -3
  18. package/dist/{ItemProperty-DBV0Iib_.js.map → ItemProperty-BdtvKrEy.js.map} +1 -1
  19. package/dist/{QueryClient-C7a0NHCt.js → QueryClient-Bmnv_moN.js} +2 -2
  20. package/dist/{QueryClient-C7a0NHCt.js.map → QueryClient-Bmnv_moN.js.map} +1 -1
  21. package/dist/{QueryClient-BnwbHtqe.js → QueryClient-hzOtFe99.js} +2 -2
  22. package/dist/{QueryClient-BnwbHtqe.js.map → QueryClient-hzOtFe99.js.map} +1 -1
  23. package/dist/bin.js +5 -5
  24. package/dist/bin.js.map +1 -1
  25. package/dist/{constants-CWg2B3Au.js → constants-Bhl5dZpN.js} +4 -1
  26. package/dist/constants-Bhl5dZpN.js.map +1 -0
  27. package/dist/{index-CQ9FS10O.js → index-BAtjd9W-.js} +3 -3
  28. package/dist/index-BAtjd9W-.js.map +1 -0
  29. package/dist/{index-BHGJ-Es9.js → index-BSR5hv7Q.js} +59 -27
  30. package/dist/index-BSR5hv7Q.js.map +1 -0
  31. package/dist/main.js +2 -2
  32. package/dist/{seed.schema.config-DDzfQguf.js → seed.schema.config-BxJYabim.js} +3 -3
  33. package/dist/{seed.schema.config-DDzfQguf.js.map → seed.schema.config-BxJYabim.js.map} +1 -1
  34. package/dist/src/AppStateSchema.ts +10 -0
  35. package/dist/src/ArweaveClient.ts +13 -0
  36. package/dist/src/Attestation.ts +21 -0
  37. package/dist/src/BaseArweaveClient.ts +13 -0
  38. package/dist/src/BaseClientManager.ts +35 -0
  39. package/dist/src/BaseDb.ts +35 -0
  40. package/dist/src/BaseEasClient.ts +14 -0
  41. package/dist/src/BaseFileManager.ts +60 -0
  42. package/dist/src/BaseItem.ts +413 -0
  43. package/dist/src/BaseItemProperty.ts +416 -0
  44. package/dist/src/BaseQueryClient.ts +13 -0
  45. package/dist/src/ClientManager.ts +63 -0
  46. package/dist/src/ConfigSchema.ts +15 -0
  47. package/dist/src/Db.ts +82 -0
  48. package/dist/src/EasClient.ts +13 -0
  49. package/dist/src/FileDownloader.ts +63 -0
  50. package/dist/src/FileManager.ts +59 -0
  51. package/dist/src/IDb.ts +7 -0
  52. package/dist/src/IEasClient.ts +2 -0
  53. package/dist/src/IItem.ts +26 -0
  54. package/dist/src/IItemProperty.ts +28 -0
  55. package/dist/src/IQueryClient.ts +11 -0
  56. package/dist/src/ImageResizer.ts +81 -0
  57. package/dist/src/Item.ts +12 -0
  58. package/dist/src/ItemProperty.ts +9 -0
  59. package/dist/src/MetadataSchema.ts +28 -0
  60. package/dist/src/ModelSchema.ts +46 -0
  61. package/dist/src/ModelUidSchema.ts +16 -0
  62. package/dist/src/PropertyUidSchema.ts +16 -0
  63. package/dist/src/QueryClient.ts +26 -0
  64. package/dist/src/Schema.ts +17 -0
  65. package/dist/src/SeedProtocolSdk.d.ts +19 -0
  66. package/dist/src/SeedSchema.ts +29 -0
  67. package/dist/src/VersionSchema.ts +16 -0
  68. package/dist/src/actors.ts +295 -0
  69. package/dist/src/addModelsToDb.ts +152 -0
  70. package/dist/src/allItems.ts +31 -0
  71. package/dist/src/analyzeInput.ts +144 -0
  72. package/dist/src/browser.app.db.config.ts +27 -0
  73. package/dist/src/browser.ts +30 -0
  74. package/dist/src/checkStatus.ts +57 -0
  75. package/dist/src/clientManagerMachine.ts +59 -0
  76. package/dist/src/configureFs.ts +98 -0
  77. package/dist/src/connectToDb.ts +41 -0
  78. package/dist/src/connectionManager.ts +67 -0
  79. package/dist/src/constants.ts +125 -0
  80. package/dist/src/content-hash.ts +30 -0
  81. package/dist/src/create.ts +39 -0
  82. package/dist/src/createMetadata.ts +77 -0
  83. package/dist/src/createNewItem.ts +61 -0
  84. package/dist/src/createPublishAttempt.ts +16 -0
  85. package/dist/src/createSeed.ts +31 -0
  86. package/dist/src/createSeeds.ts +24 -0
  87. package/dist/src/createVersion.ts +33 -0
  88. package/dist/src/dbMachine.ts +182 -0
  89. package/dist/src/deleteItem.ts +19 -0
  90. package/dist/src/download.ts +208 -0
  91. package/dist/src/drizzle.ts +78 -0
  92. package/dist/src/eas.ts +40 -0
  93. package/dist/src/environment.ts +35 -0
  94. package/dist/src/eventBus.ts +5 -0
  95. package/dist/src/events.ts +14 -0
  96. package/dist/src/fetchDataFromEas.ts +94 -0
  97. package/dist/src/fetchDbData.ts +19 -0
  98. package/dist/src/fetchRelatedItems.ts +184 -0
  99. package/dist/src/fetchSeeds.ts +45 -0
  100. package/dist/src/fetchVersions.ts +49 -0
  101. package/dist/src/files.ts +81 -0
  102. package/dist/src/filesDownload.ts +326 -0
  103. package/dist/src/fragment-masking.ts +87 -0
  104. package/dist/src/getExistingItem.ts +60 -0
  105. package/dist/src/getItem.ts +32 -0
  106. package/dist/src/getItemData.ts +99 -0
  107. package/dist/src/getItemProperties.ts +56 -0
  108. package/dist/src/getItemProperty.ts +34 -0
  109. package/dist/src/getItems.ts +70 -0
  110. package/dist/src/getMetadata.ts +40 -0
  111. package/dist/src/getModelSchemas.ts +89 -0
  112. package/dist/src/getPropertyData.ts +50 -0
  113. package/dist/src/getPublishPayload.ts +355 -0
  114. package/dist/src/getPublishUploads.ts +207 -0
  115. package/dist/src/getRelationValueData.ts +27 -0
  116. package/dist/src/getSchemaForItemProperty.ts +68 -0
  117. package/dist/src/getSchemaForModel.ts +42 -0
  118. package/dist/src/getSchemaUidForModel.ts +32 -0
  119. package/dist/src/getSeedData.ts +34 -0
  120. package/dist/src/getSegmentedItemProperties.ts +65 -0
  121. package/dist/src/getStorageTransactionIdForSeedUid.ts +38 -0
  122. package/dist/src/getVersionData.ts +46 -0
  123. package/dist/src/getVersionsForVersionUids.ts +39 -0
  124. package/dist/src/globalMachine.ts +280 -0
  125. package/dist/src/gql.ts +118 -0
  126. package/dist/src/graphql.ts +3209 -0
  127. package/dist/src/helpers.ts +273 -0
  128. package/dist/src/hydrateExistingItem.ts +137 -0
  129. package/dist/src/hydrateFromDb.ts +270 -0
  130. package/dist/src/hydrateNewItem.ts +34 -0
  131. package/dist/src/imageResize.ts +507 -0
  132. package/dist/src/index.d.ts +5 -0
  133. package/dist/src/index.ts +4 -0
  134. package/dist/src/initialize.ts +124 -0
  135. package/dist/src/internalMachine.ts +241 -0
  136. package/dist/src/itemMachineAll.ts +157 -0
  137. package/dist/src/itemMachineSingle.ts +158 -0
  138. package/dist/src/loadAppDb.ts +44 -0
  139. package/dist/src/machines.ts +66 -0
  140. package/dist/src/metadataLatest.ts +34 -0
  141. package/dist/src/migrate.ts +57 -0
  142. package/dist/src/model.ts +72 -0
  143. package/dist/src/modelClass.ts +19 -0
  144. package/dist/src/node.app.db.config.ts +41 -0
  145. package/dist/src/prepareDb.ts +29 -0
  146. package/dist/src/preparePublishRequestData.ts +81 -0
  147. package/dist/src/processItems.ts +74 -0
  148. package/dist/src/property.ts +156 -0
  149. package/dist/src/propertyMachine.ts +202 -0
  150. package/dist/src/publish.ts +28 -0
  151. package/dist/src/publishMachine.ts +77 -0
  152. package/dist/src/queries.ts +13 -0
  153. package/dist/src/recoverDeletedItem.ts +14 -0
  154. package/dist/src/reload.ts +33 -0
  155. package/dist/src/request.ts +45 -0
  156. package/dist/src/requestAll.ts +157 -0
  157. package/dist/src/resolveRelatedValue.ts +367 -0
  158. package/dist/src/resolveRemoteStorage.ts +88 -0
  159. package/dist/src/saveAppState.ts +50 -0
  160. package/dist/src/saveConfig.ts +106 -0
  161. package/dist/src/saveDataToDb.ts +145 -0
  162. package/dist/src/saveImageSrc.ts +242 -0
  163. package/dist/src/saveItemStorage.ts +156 -0
  164. package/dist/src/saveMetadata.ts +18 -0
  165. package/dist/src/savePublishService.ts +30 -0
  166. package/dist/src/saveRelation.ts +112 -0
  167. package/dist/src/seed.schema.config.ts +25 -0
  168. package/dist/src/seed.ts +10 -0
  169. package/dist/src/seedProtocol.ts +17 -0
  170. package/dist/src/services.ts +365 -0
  171. package/dist/src/setAddresses.ts +16 -0
  172. package/dist/src/sqlWasmClient.ts +88 -0
  173. package/dist/src/syncDbWithEas.ts +628 -0
  174. package/dist/src/trash.ts +29 -0
  175. package/dist/src/ts-to-proto.ts +101 -0
  176. package/dist/src/types.ts +12 -0
  177. package/dist/src/updateItemPropertyValue.ts +243 -0
  178. package/dist/src/updateMachineContext.ts +21 -0
  179. package/dist/src/updateMetadata.ts +59 -0
  180. package/dist/src/upload.ts +86 -0
  181. package/dist/src/validate.ts +45 -0
  182. package/dist/src/validateInput.ts +43 -0
  183. package/dist/src/validateItemData.ts +20 -0
  184. package/dist/src/versionData.ts +24 -0
  185. package/dist/src/waitForDb.ts +25 -0
  186. package/dist/src/waitForFiles.ts +41 -0
  187. package/dist/src/wasm.d.ts +8300 -0
  188. package/dist/types/scripts/bin.d.ts.map +1 -1
  189. package/dist/types/src/browser/helpers/FileManager.d.ts +2 -1
  190. package/dist/types/src/browser/helpers/FileManager.d.ts.map +1 -1
  191. package/dist/types/src/helpers/FileManager/BaseFileManager.d.ts +1 -0
  192. package/dist/types/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
  193. package/dist/types/src/node/helpers/FileManager.d.ts +2 -1
  194. package/dist/types/src/node/helpers/FileManager.d.ts.map +1 -1
  195. package/package.json +3 -3
  196. package/dist/FileManager-DTzkncLh.js.map +0 -1
  197. package/dist/constants-CWg2B3Au.js.map +0 -1
  198. package/dist/index-BHGJ-Es9.js.map +0 -1
  199. package/dist/index-CQ9FS10O.js.map +0 -1
  200. package/dist/package.json +0 -189
@@ -0,0 +1,416 @@
1
+ import { ActorRefFrom, createActor, SnapshotFrom, Subscription, waitFor } from 'xstate'
2
+ import { BehaviorSubject, Subscriber } from 'rxjs'
3
+ import { Static } from '@sinclair/typebox'
4
+ import { IItemProperty } from '@/interfaces/IItemProperty'
5
+ import { immerable } from 'immer'
6
+ import { CreatePropertyInstanceProps, PropertyMachineContext } from '@/types'
7
+ import { getModel } from '@/stores/modelClass'
8
+ import { propertyMachine } from './service/propertyMachine'
9
+ import { internalPropertyNames } from '@/helpers/constants'
10
+ import debug from 'debug'
11
+ import pluralize from 'pluralize'
12
+ import { eventEmitter } from '@/eventBus'
13
+ import fs from '@zenfs/core'
14
+ import { getPropertyData } from '@/db/read/getPropertyData'
15
+ import { getCorrectId } from '@/helpers'
16
+ import { TProperty } from '@/schema'
17
+
18
+ const logger = debug('app:property:class')
19
+
20
+ type ItemPropertyService = ActorRefFrom<typeof propertyMachine>
21
+ type ItemPropertySnapshot = SnapshotFrom<typeof propertyMachine>
22
+
23
+ type ItemPropertyFindProps = {
24
+ propertyName: string
25
+ propertyLocalId?: string
26
+ seedLocalId?: string
27
+ seedUid?: string
28
+ }
29
+
30
+ export abstract class BaseItemProperty<PropertyType> implements IItemProperty<PropertyType> {
31
+ protected static instanceCache: Map<
32
+ string,
33
+ { instance: BaseItemProperty<any>; refCount: number }
34
+ > = new Map()
35
+ protected readonly _service: ItemPropertyService
36
+ protected _subject: BehaviorSubject<any>
37
+ protected readonly _isRelation: boolean = false
38
+ protected readonly _isList: boolean = false
39
+ protected readonly _alias: string | undefined
40
+ protected _subscription: Subscription
41
+ protected _dataType: string | undefined
42
+ protected _schemaUid: string | undefined
43
+ [immerable] = true
44
+
45
+ constructor(initialValues: Partial<CreatePropertyInstanceProps>) {
46
+ const { modelName, propertyName, propertyValue, seedLocalId, seedUid, versionLocalId, versionUid, storageTransactionId, schemaUid } = initialValues
47
+
48
+ if (!modelName) {
49
+ throw new Error('Model name is required')
50
+ }
51
+
52
+ const ModelClass = getModel(modelName)
53
+
54
+ if (!ModelClass) {
55
+ throw new Error(`Model ${modelName} not found`)
56
+ }
57
+
58
+ if (!propertyName) {
59
+ throw new Error(`Property name not provided`)
60
+ }
61
+
62
+ const serviceInput: Partial<PropertyMachineContext> = {
63
+ propertyValue,
64
+ propertyName,
65
+ seedLocalId,
66
+ seedUid,
67
+ versionLocalId,
68
+ versionUid,
69
+ modelName: modelName,
70
+ storageTransactionId,
71
+ propertyRecordSchema: ModelClass.schema[propertyName],
72
+ schemaUid,
73
+ }
74
+
75
+
76
+
77
+ if (!internalPropertyNames.includes(propertyName)) {
78
+ let propertyNameWithoutId
79
+
80
+ const propertyRecordSchema =
81
+ ModelClass.schema[propertyNameWithoutId || propertyName]
82
+ if (propertyRecordSchema) {
83
+ this._dataType = propertyRecordSchema.dataType
84
+
85
+ serviceInput.propertyRecordSchema = propertyRecordSchema
86
+
87
+ if (propertyRecordSchema.dataType === 'Relation') {
88
+ this._isRelation = true
89
+ }
90
+
91
+ if (
92
+ propertyRecordSchema.dataType === 'List' &&
93
+ propertyRecordSchema.ref
94
+ ) {
95
+ this._isList = true
96
+ this._isRelation = true
97
+
98
+ if (propertyValue) {
99
+ try {
100
+ serviceInput.propertyValue = JSON.parse(propertyValue)
101
+ } catch (e) {
102
+ logger('List property value is not JSON', e)
103
+ }
104
+ }
105
+
106
+ const propertyNameSingular = pluralize(propertyName!, 1)
107
+
108
+ this._alias = propertyName
109
+
110
+ serviceInput.propertyName = `${propertyNameSingular}${propertyRecordSchema.ref}Ids`
111
+ }
112
+
113
+ if (!this._alias && propertyNameWithoutId) {
114
+ this._alias = propertyNameWithoutId
115
+ }
116
+ }
117
+ }
118
+
119
+ serviceInput.isRelation = this._isRelation
120
+
121
+ this._subject = new BehaviorSubject(propertyValue)
122
+ this._service = createActor(propertyMachine, {
123
+ input: serviceInput,
124
+ })
125
+
126
+ this._subscription = this._service.subscribe(
127
+ async (snapshot: ItemPropertySnapshot) => {
128
+ if (!snapshot || !snapshot.context) {
129
+ return
130
+ }
131
+
132
+ const { context } = snapshot
133
+ const { propertyRecordSchema } = context
134
+
135
+ if (context.seedLocalId) {
136
+ const cacheKey = BaseItemProperty.cacheKey(
137
+ context.seedLocalId,
138
+ context.propertyName,
139
+ )
140
+ if (!BaseItemProperty.instanceCache.has(cacheKey)) {
141
+ BaseItemProperty.instanceCache.set(cacheKey, {
142
+ instance: this,
143
+ refCount: 1,
144
+ })
145
+ }
146
+ }
147
+
148
+ let renderValue
149
+
150
+ if (
151
+ propertyRecordSchema &&
152
+ propertyRecordSchema.storageType &&
153
+ propertyRecordSchema.storageType === 'ItemStorage' &&
154
+ context.refResolvedValue &&
155
+ context.localStorageDir
156
+ ) {
157
+ const filePath = `/files/${context.localStorageDir}/${context.refResolvedValue}`
158
+ try {
159
+ const exists = await fs.promises.exists(filePath)
160
+ if (exists) {
161
+ renderValue = await fs.promises.readFile(filePath, 'utf-8')
162
+ }
163
+ if (!exists) {
164
+ renderValue = 'No file found'
165
+ }
166
+ } catch (e) {
167
+ logger(
168
+ `[ItemProperty] [${context.seedLocalId}] [${context.propertyName}] [storageType] error`,
169
+ e,
170
+ )
171
+ renderValue = 'No file found'
172
+ }
173
+ }
174
+
175
+ if (!renderValue) {
176
+ renderValue = context.renderValue || context.propertyValue
177
+ }
178
+
179
+ let transformedPropertyName = propertyName
180
+
181
+ const skipTransform =
182
+ internalPropertyNames.includes(propertyName) || !!this._alias
183
+
184
+ if (!skipTransform && transformedPropertyName.endsWith('Id')) {
185
+ transformedPropertyName = transformedPropertyName.slice(0, -2)
186
+ }
187
+
188
+ if (!skipTransform && transformedPropertyName.endsWith('Ids')) {
189
+ transformedPropertyName = transformedPropertyName.slice(0, -3)
190
+ }
191
+
192
+ if (skipTransform && this._alias) {
193
+ transformedPropertyName = this._alias
194
+ }
195
+
196
+ if (skipTransform && !this._alias) {
197
+ }
198
+
199
+ if (this._subject.value === renderValue) {
200
+ return
201
+ }
202
+
203
+ this._subject.next(renderValue)
204
+ // TODO: Maybe have this only update the property?
205
+ // if (context.seedLocalId || context.seedUid) {
206
+ // eventEmitter.emit(`property.${context.seedUid || context.seedLocalId}.${propertyName}.update`)
207
+ // }
208
+ // if (context.seedUid) {
209
+ // eventEmitter.emit(`item.${modelName}.${context.seedUid}.update`)
210
+ // }
211
+ },
212
+ )
213
+
214
+ this._service.start()
215
+ }
216
+
217
+ static PlatformClass: typeof BaseItemProperty
218
+
219
+ static setPlatformClass(platformClass: typeof BaseItemProperty) {
220
+ this.PlatformClass = platformClass
221
+ }
222
+
223
+ static create(
224
+ props: Partial<CreatePropertyInstanceProps>,
225
+ ): BaseItemProperty<any> | undefined {
226
+ const { propertyName, seedLocalId, seedUid, versionLocalId, versionUid } =
227
+ props
228
+ if (!propertyName || (!seedLocalId && !seedUid)) {
229
+ return
230
+ }
231
+ const cacheKey = this.cacheKey(
232
+ (seedUid || seedLocalId) as string,
233
+ propertyName,
234
+ )
235
+ if (seedLocalId && propertyName) {
236
+ if (this.instanceCache.has(cacheKey)) {
237
+ const { instance, refCount } = this.instanceCache.get(cacheKey)!
238
+ this.instanceCache.set(cacheKey, {
239
+ instance,
240
+ refCount: refCount + 1,
241
+ })
242
+ return instance
243
+ }
244
+ if (!this.instanceCache.has(cacheKey)) {
245
+ const newInstance = new this(props)
246
+ this.instanceCache.set(cacheKey, {
247
+ instance: newInstance,
248
+ refCount: 1,
249
+ })
250
+ return newInstance
251
+ }
252
+ }
253
+ if (seedUid && propertyName) {
254
+ if (this.instanceCache.has(cacheKey)) {
255
+ const { instance, refCount } = this.instanceCache.get(cacheKey)!
256
+ this.instanceCache.set(cacheKey, { instance, refCount: refCount + 1 })
257
+ return instance
258
+ }
259
+ if (!this.instanceCache.has(cacheKey)) {
260
+ const newInstance = new this(props)
261
+ this.instanceCache.set(cacheKey, { instance: newInstance, refCount: 1 })
262
+ return newInstance
263
+ }
264
+ }
265
+ return new this(props)
266
+ }
267
+
268
+ static async find({
269
+ propertyName,
270
+ seedLocalId,
271
+ seedUid,
272
+ }: ItemPropertyFindProps): Promise<IItemProperty<any> | undefined> {
273
+ if ((!seedLocalId && !seedUid) || !propertyName) {
274
+ return
275
+ }
276
+ const cacheKeyId = seedUid || seedLocalId
277
+ const cacheKey = BaseItemProperty.cacheKey(cacheKeyId!, propertyName)
278
+ if (this.instanceCache.has(cacheKey)) {
279
+ const { instance, refCount } = this.instanceCache.get(cacheKey)!
280
+ this.instanceCache.set(cacheKey, {
281
+ instance,
282
+ refCount: refCount + 1,
283
+ })
284
+ return instance
285
+ }
286
+ const propertyData = await getPropertyData({
287
+ propertyName,
288
+ seedLocalId,
289
+ seedUid,
290
+ })
291
+ if (!propertyData) {
292
+ return
293
+ }
294
+ return BaseItemProperty.create(propertyData)
295
+ }
296
+
297
+ static cacheKey(seedLocalIdOrUid: string, propertyName: string): string {
298
+ const { uid, localId } = getCorrectId(seedLocalIdOrUid)
299
+ return `Item_${uid || localId}_${propertyName}`
300
+ }
301
+
302
+ getService() {
303
+ return this._service
304
+ }
305
+
306
+ private _getSnapshot(): ItemPropertySnapshot {
307
+ return this._service.getSnapshot() as ItemPropertySnapshot
308
+ }
309
+
310
+ get localId() {
311
+ return this._getSnapshot().context.localId
312
+ }
313
+
314
+ get uid() {
315
+ return this._getSnapshot().context.uid
316
+ }
317
+
318
+ get seedLocalId() {
319
+ return this._getSnapshot().context.seedLocalId
320
+ }
321
+
322
+ get seedUid() {
323
+ return this._getSnapshot().context.seedUid
324
+ }
325
+
326
+ get schemaUid() {
327
+ return this._getSnapshot().context.schemaUid
328
+ }
329
+
330
+ get propertyName() {
331
+ if (this._alias) {
332
+ return this._alias
333
+ }
334
+ return this._getSnapshot().context.propertyName
335
+ }
336
+
337
+ get modelName() {
338
+ return this._getSnapshot().context.modelName
339
+ }
340
+
341
+ get propertyDef(): Static<typeof TProperty> | undefined {
342
+ return this._getSnapshot().context.propertyRecordSchema
343
+ }
344
+
345
+ get localStoragePath(): string | void {
346
+ if (this.propertyDef && this.propertyDef.localStorageDir) {
347
+ return `/files${this.propertyDef.localStorageDir}/${this._getSnapshot().context.refResolvedValue}`
348
+ }
349
+ if (this._getSnapshot().context.localStorageDir) {
350
+ return `/files${this._getSnapshot().context.localStorageDir}/${this._getSnapshot().context.refResolvedValue}`
351
+ }
352
+ }
353
+
354
+ get versionLocalId(): string | undefined {
355
+ return this._getSnapshot().context.versionLocalId
356
+ }
357
+
358
+ get status() {
359
+ return this._getSnapshot().value
360
+ }
361
+
362
+ get alias() {
363
+ return this._alias
364
+ }
365
+
366
+ get value() {
367
+ // logger(
368
+ // `[XXXXXXXXXX] [value] [get] subjectValue: ${this._subject.value} serviceValue: ${this._service.getSnapshot().context.renderValue}`,
369
+ // )
370
+ return this._subject.value
371
+ }
372
+
373
+ set value(value: any) {
374
+ if (this._subject.value === value) {
375
+ return
376
+ }
377
+ const context = this._service.getSnapshot().context
378
+ if (!context.propertyRecordSchema) {
379
+ this._subject.next(value)
380
+ }
381
+ this._service.send({
382
+ type: 'save',
383
+ newValue: value,
384
+ })
385
+ }
386
+
387
+ get published(): boolean {
388
+ return !!this._getSnapshot().context.uid
389
+ }
390
+
391
+ subscribe(callback: Partial<Subscriber<any>>) {
392
+ return this._subject.subscribe(callback)
393
+ }
394
+
395
+ async save(): Promise<void> {
396
+ await waitFor(
397
+ this._service,
398
+ (snapshot) => !snapshot.context.isSaving && snapshot.value === 'idle',
399
+ {
400
+ timeout: 10_000,
401
+ },
402
+ )
403
+ // return new Promise((resolve) => {
404
+ // const saveSub = this._service.subscribe((snapshot) => {
405
+ // if (!snapshot.context.isSaving) {
406
+ // saveSub.unsubscribe()
407
+ // resolve()
408
+ // }
409
+ // })
410
+ // })
411
+ }
412
+
413
+ unload() {
414
+ this._service.stop()
415
+ }
416
+ }
@@ -0,0 +1,13 @@
1
+ import { IQueryClient } from "@/interfaces/IQueryClient"
2
+
3
+ export abstract class BaseQueryClient {
4
+ static PlatformClass: typeof BaseQueryClient
5
+
6
+ static setPlatformClass(platformClass: typeof BaseQueryClient) {
7
+ this.PlatformClass = platformClass
8
+ }
9
+
10
+ static getQueryClient(): IQueryClient {
11
+ return this.PlatformClass.getQueryClient()
12
+ }
13
+ }
@@ -0,0 +1,63 @@
1
+ import debug from 'debug'
2
+ import { createActor, waitFor } from 'xstate'
3
+ import { clientManagerMachine } from '@/client/clientManagerMachine'
4
+ import { SeedConstructorOptions } from '@/types/index'
5
+ import { BaseDb } from '@/db/Db/BaseDb'
6
+ import { appState } from '@/seedSchema'
7
+ import { eq } from 'drizzle-orm'
8
+ import { CLIENT_NOT_INITIALIZED } from '@/helpers/constants'
9
+
10
+ const logger = debug('app:client')
11
+
12
+ export const clientManager = createActor(clientManagerMachine, {
13
+ input: {
14
+ isInitialized: false,
15
+ }
16
+ })
17
+
18
+ const subscription = clientManager.subscribe(( snapshot ) => {
19
+ logger('ClientManager snapshot.value:', snapshot.value)
20
+ logger('ClientManager snapshot.context.isInitialized:', snapshot.context.isInitialized)
21
+ })
22
+
23
+ clientManager.start()
24
+
25
+ const ensureInitialized = () => {
26
+ if (!clientManager.getSnapshot().context.isInitialized) {
27
+ throw new Error(CLIENT_NOT_INITIALIZED);
28
+ }
29
+ }
30
+
31
+ export const ClientManager = {
32
+ isInitialized: () => clientManager.getSnapshot().context.isInitialized,
33
+ getService: () => {
34
+ ensureInitialized();
35
+ return clientManager;
36
+ },
37
+ init: async (options: SeedConstructorOptions) => {
38
+ clientManager.send({ type: 'init', options });
39
+ await waitFor(clientManager, (snapshot) => snapshot.context.isInitialized);
40
+ },
41
+ setAddresses: async (addresses: string[]) => {
42
+ ensureInitialized();
43
+ logger('setAddresses', addresses);
44
+ clientManager.send({ type: 'setAddresses', addresses });
45
+ await waitFor(clientManager, (snapshot) => !snapshot.context.isSaving);
46
+ logger('setAddresses success', addresses);
47
+ },
48
+ getAddresses: async () => {
49
+ ensureInitialized();
50
+ const db = await BaseDb.getAppDb();
51
+ const results = await db.select().from(appState).where(eq(appState.key, 'addresses'));
52
+ return JSON.parse(results[0]?.value);
53
+ },
54
+ stop: () => {
55
+ ensureInitialized();
56
+ clientManager.stop();
57
+ },
58
+ unload: () => {
59
+ ensureInitialized();
60
+ clientManager.stop();
61
+ subscription.unsubscribe();
62
+ },
63
+ }
@@ -0,0 +1,15 @@
1
+ import { blob, int, sqliteTable, text, check, } from 'drizzle-orm/sqlite-core'
2
+ import { sql } from 'drizzle-orm'
3
+
4
+ export const config = sqliteTable('config', {
5
+ id: int('id').primaryKey({ autoIncrement: true }),
6
+ key: text('key').notNull(),
7
+ text: text('text'),
8
+ json: text('json', {mode: 'json'}),
9
+ blob: blob('blob', {mode: 'buffer'}),
10
+ }, () => {
11
+ return {
12
+ // Add a custom check constraint
13
+ atLeastOneNotNull: check('hasValue', sql`key IS NOT NULL OR text IS NOT NULL OR json IS NOT NULL OR blob IS NOT NULL`),
14
+ }
15
+ })
package/dist/src/Db.ts ADDED
@@ -0,0 +1,82 @@
1
+ import { BaseDb } from "@/db/Db/BaseDb";
2
+ import { IDb } from "@/interfaces";
3
+ import nodeAppDbConfig from "./node.app.db.config";
4
+ import { BetterSQLite3Database, drizzle } from "drizzle-orm/better-sqlite3";
5
+ import { defineConfig, } from "drizzle-kit";
6
+ import path from "path";
7
+ import { DrizzleConfig, } from "drizzle-orm";
8
+ import { isBrowser } from '@/helpers/environment'
9
+ import {migrate} from 'drizzle-orm/better-sqlite3/migrator'
10
+ import fs from 'fs'
11
+ import debug from 'debug'
12
+ import { appState } from '@/seedSchema'
13
+
14
+ const logger = debug('app:node:db:Db')
15
+
16
+ const getConfig = (dotSeedDir: string) => {
17
+
18
+ let schemaDir = `${dotSeedDir}/schema/*Schema.ts`
19
+ if (!isBrowser()) {
20
+ schemaDir = path.join(process.cwd(), 'schema')
21
+ }
22
+
23
+ const nodeDbConfig = defineConfig({
24
+ schema: schemaDir,
25
+ dialect: 'sqlite',
26
+ out: `${dotSeedDir}/db`,
27
+ dbCredentials: {
28
+ url: `${dotSeedDir}/db/app_db.sqlite3`,
29
+ }
30
+ }) as DrizzleConfig & { dbCredentials: { url: string } }
31
+
32
+ return nodeDbConfig
33
+ }
34
+
35
+ class Db extends BaseDb implements IDb {
36
+ static db: BetterSQLite3Database
37
+ constructor() {
38
+ super()
39
+ }
40
+
41
+ static getAppDb() {
42
+ return this.db
43
+ }
44
+
45
+ static isAppDbReady() {
46
+ return true
47
+ }
48
+
49
+ static async prepareDb(filesDir: string) {
50
+ const nodeDbConfig = getConfig(filesDir)
51
+
52
+ this.db = drizzle({
53
+ ...nodeDbConfig,
54
+ logger: true,
55
+ })
56
+
57
+ if (!this.db) {
58
+ throw new Error('Db not found')
59
+ }
60
+
61
+ return this.db
62
+ }
63
+
64
+ static async connectToDb(pathToDir: string, dbName: string) {
65
+
66
+ return {
67
+ id: this.db.constructor.name
68
+ }
69
+ }
70
+
71
+ static async migrate(pathToDbDir: string, dbName: string, dbId: string) {
72
+ migrate(this.db, { migrationsFolder: pathToDbDir })
73
+ const queryResult = await this.db.select().from(appState)
74
+ logger('queryResult', queryResult)
75
+
76
+ return this.db
77
+ }
78
+ }
79
+
80
+ BaseDb.setPlatformClass(Db)
81
+
82
+ export { Db }
@@ -0,0 +1,13 @@
1
+ import { BaseEasClient } from "@/helpers/EasClient/BaseEasClient"
2
+ import { EAS_ENDPOINT } from "@/services/internal/constants"
3
+ import { GraphQLClient } from "graphql-request"
4
+
5
+ class EasClient extends BaseEasClient {
6
+ static getEasClient() {
7
+ return new GraphQLClient(EAS_ENDPOINT)
8
+ }
9
+ }
10
+
11
+ BaseEasClient.setPlatformClass(EasClient)
12
+
13
+ export { EasClient }
@@ -0,0 +1,63 @@
1
+ import { saveAppState } from '@/db/write/saveAppState.js';
2
+ import filesDownload from './filesDownload.js'
3
+
4
+
5
+
6
+ export class FileDownloader {
7
+ private cores: number
8
+ private workersArchive: Worker[] = []
9
+ private workerBlobUrl: string
10
+
11
+ constructor() {
12
+ this.cores = Math.min(navigator.hardwareConcurrency || 4, 4);
13
+
14
+ this.workerBlobUrl = globalThis.URL.createObjectURL(
15
+ new Blob([filesDownload], { type: 'application/javascript' })
16
+ )
17
+ }
18
+
19
+ public downloadAll = async ({transactionIds, arweaveHost, excludedTransactions}: DownloadAllFilesParams): Promise<void> => {
20
+
21
+ if (this.workersArchive.length > 0) {
22
+ for (let i = 0; i < this.workersArchive.length; i++) {
23
+ this.workersArchive[i].terminate()
24
+ delete this.workersArchive[i]
25
+ }
26
+ this.workersArchive = []
27
+ }
28
+
29
+ const worker = new Worker(this.workerBlobUrl);
30
+
31
+ this.workersArchive.push(worker)
32
+
33
+ const localExcludedTransactions = new Set(excludedTransactions)
34
+
35
+ return new Promise((resolve, reject) => {
36
+ worker.onmessage = (e) => {
37
+ console.log('filesDownload main thread onmessage', e.data);
38
+
39
+ if (e.data.message === 'excludeTransaction') {
40
+ localExcludedTransactions.add(e.data.transactionId)
41
+ }
42
+
43
+ if (e.data.done) {
44
+ saveAppState('excludedTransactions', JSON.stringify(Array.from(localExcludedTransactions)))
45
+ .then(() => {
46
+ resolve(e.data)
47
+ })
48
+ .catch((error) => {
49
+ reject(error)
50
+ })
51
+ }
52
+ if (e.data.error) {
53
+ reject(e.data.error)
54
+ }
55
+ }
56
+
57
+ worker.postMessage({
58
+ transactionIds,
59
+ arweaveHost,
60
+ });
61
+ })
62
+ }
63
+ }