@seedprotocol/sdk 0.2.10 → 0.2.11

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.
@@ -1,127 +1,278 @@
1
- import { EventObject, fromCallback, Subscription } from 'xstate'
2
- import { isNode, isReactNative } from '@/shared'
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { GET_SCHEMAS } from '@/Item/queries'
3
+ import pluralize from 'pluralize'
4
+ import { BaseEasClient } from '@/helpers/EasClient/BaseEasClient'
5
+ import { BaseQueryClient } from '@/helpers/QueryClient/BaseQueryClient'
6
+ import { toSnakeCase } from '@/helpers'
3
7
  import {
4
- GLOBAL_INITIALIZING_CREATE_ALL_ITEMS_SERVICES,
5
- GLOBAL_INITIALIZING_INTERNAL_SERVICE_READY,
6
- GLOBAL_INITIALIZING_SEND_CONFIG,
7
- } from '@/services/internal/constants'
8
- import debug from 'debug'
9
- import { FromCallbackInput, GlobalMachineContext } from '@/types'
8
+ models as modelsTable,
9
+ modelUids,
10
+ properties,
11
+ propertyUids,
12
+ } from '@/seedSchema'
13
+ import { eq } from 'drizzle-orm'
14
+ import { SchemaWhereInput } from '@/graphql/gql/graphql'
15
+ import { INTERNAL_DATA_TYPES } from '@/helpers/constants'
16
+ import { getAddressesFromDb } from '@/helpers/db'
17
+ import { eventEmitter } from '@/eventBus'
10
18
  import { BaseDb } from '@/db/Db/BaseDb'
11
- import { appState } from '@/seedSchema'
12
- import { like } from 'drizzle-orm'
13
- import { fetchSchemaUids } from '@/stores/eas'
14
19
 
15
- const logger = debug('app:services:global:actors:initialize')
20
+ import { AllItemsMachineContext, FromCallbackInput } from '@/types'
21
+
22
+
23
+ type Times = {
24
+ initialize?: {
25
+ start: number | null
26
+ end: number | null
27
+ }
28
+ fetchDbData?: {
29
+ start: number | null
30
+ end: number | null
31
+ }
32
+ fetchSeeds?: {
33
+ start: number | null
34
+ end: number | null
35
+ }
36
+ fetchVersions?: {
37
+ start: number | null
38
+ end: number | null
39
+ }
40
+ fetchRelatedItems?: {
41
+ start: number | null
42
+ end: number | null
43
+ }
44
+ processItems?: {
45
+ start: number | null
46
+ end: number | null
47
+ }
48
+ }
49
+
50
+ type InternalDataType = keyof typeof INTERNAL_DATA_TYPES;
16
51
 
17
52
  export const initialize = fromCallback<
18
53
  EventObject,
19
- FromCallbackInput<GlobalMachineContext, EventObject>
20
- >(({ sendBack, input: { event, context } }) => {
21
- const { internalService, models, endpoints, arweaveDomain } = context
54
+ FromCallbackInput<AllItemsMachineContext>
55
+ >(({ sendBack, input: { context } }) => {
56
+ const { modelName, modelAddedToDb, ModelClass, times } = context
22
57
 
23
- const { addresses } = event
58
+ const newTimes: Times = {
59
+ initialize: {
60
+ start: Date.now(),
61
+ end: null,
62
+ },
63
+ }
24
64
 
25
- let environment = 'browser'
65
+ let modelNameLowercase: string | undefined
66
+ let modelNamePlural: string | undefined
67
+ let queryVariables: Record<string, unknown> | undefined
68
+ let appDb
26
69
 
27
- if (isNode()) {
28
- environment = 'node'
29
- }
70
+ const _initialize = async () => {
71
+ appDb = BaseDb.getAppDb()
30
72
 
31
- if (isReactNative()) {
32
- environment = 'react-native'
33
- }
73
+ // const rows = await getItemsDataFromDb(modelName)
74
+ //
75
+ // if (rows && rows.length > 0) {
76
+ // for (const itemData of rows) {
77
+ // const {
78
+ // versionLocalId,
79
+ // versionUid,
80
+ // createdAt,
81
+ // seedLocalId,
82
+ // seedUid,
83
+ // attestationCreatedAt,
84
+ // } = itemData
85
+ //
86
+ // eventEmitter.emit('item.create.request', {
87
+ // itemData: {
88
+ // versionLocalId,
89
+ // versionUid,
90
+ // createdAt,
91
+ // seedLocalId,
92
+ // seedUid,
93
+ // attestationCreatedAt,
94
+ // },
95
+ // ModelClass,
96
+ // })
97
+ // }
98
+ // }
34
99
 
35
- let internalSubscription: Subscription | undefined
36
- let easSubscription: Subscription | undefined
100
+ modelNameLowercase = modelName.toLowerCase()
101
+ modelNamePlural = pluralize(modelNameLowercase!)
37
102
 
38
- if (environment === 'browser' && models) {
39
- const _initFileSystem = async (): Promise<void> => {
40
- return
41
- // return new Promise((resolve) => {
42
- // })
103
+ const queryClient = BaseQueryClient.getQueryClient()
104
+ const easClient = BaseEasClient.getEasClient()
105
+
106
+ const modelSchemas = await queryClient.fetchQuery({
107
+ queryKey: [`getSchemas${modelName}`],
108
+ queryFn: async () =>
109
+ easClient.request(GET_SCHEMAS, {
110
+ where: {
111
+ schema: {
112
+ equals: `bytes32 ${toSnakeCase(modelName)}`,
113
+ },
114
+ },
115
+ }),
116
+ })
117
+
118
+ if (
119
+ !modelSchemas ||
120
+ !modelSchemas.schemas ||
121
+ modelSchemas.schemas.length === 0
122
+ ) {
123
+ throw new Error(`No schema found for ${modelName}`)
43
124
  }
44
125
 
45
- const _initInternal = async (): Promise<void> => {
46
- return new Promise((resolve) => {
47
- internalSubscription = internalService.subscribe((snapshot) => {
48
- logger('[sdk] [internal] snapshot', snapshot)
49
- if (snapshot.value === 'ready') {
50
- resolve()
51
- }
52
- })
53
- internalService.send({
54
- type: 'init',
55
- endpoints,
56
- addresses,
57
- arweaveDomain,
58
- })
126
+ const modelSchema = modelSchemas.schemas[0]
127
+
128
+ if (!modelSchema.id) {
129
+ throw new Error(
130
+ `No schema ID found for schema ${JSON.stringify(modelSchema)}`,
131
+ )
132
+ }
133
+
134
+ const foundModels = await appDb
135
+ .select({
136
+ id: modelsTable.id,
137
+ name: modelsTable.name,
138
+ uid: modelUids.uid,
59
139
  })
140
+ .from(modelsTable)
141
+ .leftJoin(modelUids, eq(modelsTable.id, modelUids.modelId))
142
+ .where(eq(modelsTable.name, modelName))
143
+ .limit(1)
144
+
145
+ const foundModel = foundModels[0]
146
+
147
+ if (!foundModel) {
148
+ sendBack({ type: 'modelNotFound', modelName })
149
+ return
60
150
  }
61
151
 
62
- const _initAllItemsServices = async (): Promise<void> => {
63
- const appDb = BaseDb.getAppDb()
152
+ await appDb
153
+ .insert(modelUids)
154
+ .values({
155
+ modelId: foundModel.id,
156
+ uid: modelSchema.id,
157
+ })
158
+ .onConflictDoNothing()
64
159
 
65
- const rows = await appDb
66
- .select()
67
- .from(appState)
68
- .where(like(appState.key, 'snapshot__%'))
160
+ const foundPropertiesDb = await appDb
161
+ .select({
162
+ id: properties.id,
163
+ name: properties.name,
164
+ dataType: properties.dataType,
165
+ uid: propertyUids.uid,
166
+ })
167
+ .from(properties)
168
+ .fullJoin(propertyUids, eq(properties.id, propertyUids.propertyId))
169
+ .where(eq(properties.modelId, foundModel.id))
69
170
 
70
- const payloadObj = {
71
- create: {},
72
- restore: {},
171
+ if (foundPropertiesDb && foundPropertiesDb.length > 0) {
172
+ const queryVariables: { where: SchemaWhereInput } = {
173
+ where: {
174
+ OR: [],
175
+ },
73
176
  }
74
177
 
75
- const modelNamesRestored: string[] = []
178
+ for (const foundPropertyDb of foundPropertiesDb) {
179
+ if (foundPropertyDb.name && foundPropertyDb.dataType) {
180
+ const easDatatype = INTERNAL_DATA_TYPES[foundPropertyDb.dataType as InternalDataType].eas
76
181
 
77
- if (rows && rows.length > 0) {
78
- for (const row of rows) {
79
- const modelName = row.key.replace('snapshot__', '')
80
- payloadObj.restore[modelName] = JSON.parse(row.value)
81
- modelNamesRestored.push(modelName)
182
+ let easPropertyName = toSnakeCase(foundPropertyDb.name)
183
+
184
+ if (foundPropertyDb.dataType === 'Relation') {
185
+ easPropertyName += '_id'
186
+ }
187
+
188
+ queryVariables.where.OR!.push({
189
+ schema: {
190
+ equals: `${easDatatype} ${easPropertyName}`,
191
+ },
192
+ })
82
193
  }
83
194
  }
84
- for (const [modelName, ModelClass] of Object.entries(models)) {
85
- if (!modelNamesRestored.includes(modelName)) {
86
- payloadObj.create[modelName] = ModelClass
195
+
196
+ const foundPropertySchemas = await queryClient.fetchQuery({
197
+ queryKey: [`getPropertySchemas${modelName}`],
198
+ queryFn: async () => easClient.request(GET_SCHEMAS, queryVariables),
199
+ })
200
+
201
+ const tempExclusions = ['html', 'json']
202
+
203
+ for (const foundProperty of foundPropertiesDb) {
204
+ if (tempExclusions.includes(foundProperty.name)) {
205
+ continue
206
+ }
207
+ const easDatatype = INTERNAL_DATA_TYPES[foundProperty.dataType as InternalDataType].eas
208
+
209
+ let easPropertyName = toSnakeCase(foundProperty.name)
210
+
211
+ if (foundProperty.dataType === 'Relation') {
212
+ easPropertyName += '_id'
213
+ }
214
+
215
+ const regex = new RegExp(`${easDatatype} ${easPropertyName}`)
216
+ const propertySchema = foundPropertySchemas.schemas.find((s) =>
217
+ regex.test(s.schema),
218
+ )
219
+
220
+ if (!propertySchema) {
221
+ // TODO: We should create the schema here?
222
+ continue
87
223
  }
224
+ await appDb
225
+ .insert(propertyUids)
226
+ .values({
227
+ propertyId: foundProperty.id,
228
+ uid: propertySchema.id,
229
+ })
230
+ .onConflictDoNothing()
88
231
  }
89
- sendBack({
90
- type: GLOBAL_INITIALIZING_CREATE_ALL_ITEMS_SERVICES,
91
- ...payloadObj,
92
- })
93
232
  }
94
233
 
95
- const _initEas = async (): Promise<void> => {
96
- await fetchSchemaUids()
234
+ const addresses = await getAddressesFromDb()
235
+
236
+ queryVariables = {
237
+ where: {
238
+ attester: {
239
+ in: addresses,
240
+ },
241
+ schemaId: {
242
+ equals: modelSchema.id,
243
+ },
244
+ decodedDataJson: {
245
+ contains: modelSchema.id,
246
+ },
247
+ },
97
248
  }
249
+ }
98
250
 
99
- _initFileSystem().then(() => {
100
- logger('[global/actors] File system initialized')
251
+ const initializeHandler = () => {
252
+ _initialize().then(() => {
253
+ sendBack({
254
+ type: 'initializeSuccess',
255
+ modelName,
256
+ modelNameLowercase,
257
+ modelNamePlural,
258
+ queryVariables,
259
+ })
260
+ newTimes!.initialize!.end = Date.now()
261
+ sendBack({ type: 'updateTimes', times: newTimes })
101
262
  })
263
+ }
102
264
 
103
- _initInternal()
104
- .then(() => {
105
- return _initAllItemsServices()
106
- })
107
- .then(() => {
108
- return _initEas()
109
- })
110
- .then(() => {
111
- logger('[global/actors] Internal initialized')
112
- sendBack({ type: GLOBAL_INITIALIZING_INTERNAL_SERVICE_READY })
113
- internalSubscription?.unsubscribe()
114
- })
265
+ if (modelAddedToDb) {
266
+ initializeHandler()
267
+ }
115
268
 
116
- // _initEas().then(() => {
117
- // logger('EAS initialized')
118
- // })
269
+ const dbReadyHandler = (event) => {
270
+ initializeHandler()
119
271
  }
120
272
 
121
- sendBack({ type: GLOBAL_INITIALIZING_SEND_CONFIG, environment })
273
+ eventEmitter.addListener('allDbsLoaded', dbReadyHandler)
122
274
 
123
275
  return () => {
124
- internalSubscription?.unsubscribe()
125
- easSubscription?.unsubscribe()
276
+ eventEmitter.removeListener('allDbsLoaded', dbReadyHandler)
126
277
  }
127
278
  })
@@ -666,6 +666,9 @@ const syncDbWithEasHandler: DebouncedFunc<any> = throttle(
666
666
  itemSeeds,
667
667
  })
668
668
 
669
+ const queryClient = BaseQueryClient.getQueryClient()
670
+ const easClient = BaseEasClient.getEasClient()
671
+
669
672
  const { itemVersions } = await queryClient.fetchQuery({
670
673
  queryKey: [`getVersionsForAllModels`],
671
674
  queryFn: async () =>
@@ -1 +1 @@
1
- {"version":3,"file":"syncDbWithEas.d.ts","sourceRoot":"","sources":["../../../../../src/events/item/syncDbWithEas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAuB,MAAM,WAAW,CAAA;AAymBzE,QAAA,MAAM,oBAAoB,EAAE,aAAa,CAAC,GAAG,CA+F5C,CAAA;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAA"}
1
+ {"version":3,"file":"syncDbWithEas.d.ts","sourceRoot":"","sources":["../../../../../src/events/item/syncDbWithEas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAuB,MAAM,WAAW,CAAA;AAymBzE,QAAA,MAAM,oBAAoB,EAAE,aAAa,CAAC,GAAG,CAkG5C,CAAA;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seedprotocol/sdk",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "description": "The SDK for Seed Protocol",
5
5
  "type": "module",
6
6
  "engines": {