@seedprotocol/sdk 0.1.67 → 0.1.70

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 (31) hide show
  1. package/dist/{index-BJn9UAOX.js → index-B6WilINl.js} +6 -6
  2. package/dist/index-B6WilINl.js.map +1 -0
  3. package/dist/{index-nGDuz8NN.js → index-Cy1fke9s.js} +575 -535
  4. package/dist/index-Cy1fke9s.js.map +1 -0
  5. package/dist/main.js +4 -4
  6. package/dist/{seed.schema.config-miFErQ6h.js → seed.schema.config-dylVDX7W.js} +5 -5
  7. package/dist/{seed.schema.config-miFErQ6h.js.map → seed.schema.config-dylVDX7W.js.map} +1 -1
  8. package/dist/src/createMetadata.ts +4 -0
  9. package/dist/src/getItems.ts +2 -0
  10. package/dist/src/getVersionData.ts +1 -1
  11. package/dist/src/hydrateFromDb.ts +28 -1
  12. package/dist/src/index.ts +104 -19
  13. package/dist/src/propertyMachine.ts +12 -0
  14. package/dist/src/saveImageSrc.ts +11 -2
  15. package/dist/src/updateItemPropertyValue.ts +230 -0
  16. package/dist/src/write.ts +2 -228
  17. package/dist/types/src/browser/db/read/getItems.d.ts.map +1 -1
  18. package/dist/types/src/browser/db/read/getVersionData.d.ts +1 -1
  19. package/dist/types/src/browser/db/read/getVersionData.d.ts.map +1 -1
  20. package/dist/types/src/browser/db/write/createMetadata.d.ts.map +1 -1
  21. package/dist/types/src/browser/db/write/updateItemPropertyValue.d.ts +5 -0
  22. package/dist/types/src/browser/db/write/updateItemPropertyValue.d.ts.map +1 -0
  23. package/dist/types/src/browser/db/write.d.ts +0 -16
  24. package/dist/types/src/browser/db/write.d.ts.map +1 -1
  25. package/dist/types/src/browser/property/actors/hydrateFromDb.d.ts.map +1 -1
  26. package/dist/types/src/browser/property/actors/saveValueToDb/index.d.ts.map +1 -1
  27. package/dist/types/src/browser/property/actors/saveValueToDb/saveImageSrc.d.ts.map +1 -1
  28. package/dist/types/src/browser/property/propertyMachine.d.ts.map +1 -1
  29. package/package.json +1 -1
  30. package/dist/index-BJn9UAOX.js.map +0 -1
  31. package/dist/index-nGDuz8NN.js.map +0 -1
package/dist/main.js CHANGED
@@ -1,4 +1,4 @@
1
- export { h as ImageSrc, I as Item, j as ItemProperty, J as Json, L as List, M as Model, P as Property, R as Relation, T as Text, s as client, t as getCorrectId, r as getGlobalService, m as useCreateItem, o as useDeleteItem, p as useGlobalServiceStatus, k as useItem, l as useItemProperties, n as useItemProperty, u as useItems, q as useServices, w as withSeed } from './index-nGDuz8NN.js';
1
+ export { h as ImageSrc, I as Item, j as ItemProperty, J as Json, L as List, M as Model, P as Property, R as Relation, T as Text, s as client, t as getCorrectId, r as getGlobalService, m as useCreateItem, o as useDeleteItem, p as useGlobalServiceStatus, k as useItem, l as useItemProperties, n as useItemProperty, u as useItems, q as useServices, w as withSeed } from './index-Cy1fke9s.js';
2
2
  import 'immer';
3
3
  import 'reflect-metadata';
4
4
  import './constants-BLctWkrn.js';
@@ -14,14 +14,14 @@ import 'nanoid-dictionary';
14
14
  import 'debug';
15
15
  import 'lodash-es';
16
16
  import 'drizzle-orm/sqlite-core';
17
+ import 'react';
18
+ import 'rxjs';
19
+ import 'pluralize';
17
20
  import 'eventemitter3';
18
21
  import '@tanstack/react-query';
19
22
  import 'graphql-request';
20
23
  import '@tanstack/query-sync-storage-persister';
21
24
  import '@tanstack/react-query-persist-client';
22
- import 'react';
23
- import 'rxjs';
24
- import 'pluralize';
25
25
  import '@statelyai/inspect';
26
26
  import 'drizzle-orm/sqlite-proxy';
27
27
  import '@zenfs/dom';
@@ -1,6 +1,6 @@
1
1
  import { _ as __decorate, a as __metadata } from './constants-BLctWkrn.js';
2
2
  import 'drizzle-orm';
3
- import { T as Text, M as Model } from './index-nGDuz8NN.js';
3
+ import { T as Text, M as Model } from './index-Cy1fke9s.js';
4
4
  import 'react';
5
5
  import 'reflect-metadata';
6
6
  import 'xstate';
@@ -15,14 +15,14 @@ import 'nanoid-dictionary';
15
15
  import 'debug';
16
16
  import 'lodash-es';
17
17
  import 'drizzle-orm/sqlite-core';
18
+ import 'rxjs';
19
+ import 'immer';
20
+ import 'pluralize';
18
21
  import 'eventemitter3';
19
22
  import '@tanstack/react-query';
20
23
  import 'graphql-request';
21
24
  import '@tanstack/query-sync-storage-persister';
22
25
  import '@tanstack/react-query-persist-client';
23
- import 'rxjs';
24
- import 'immer';
25
- import 'pluralize';
26
26
  import '@statelyai/inspect';
27
27
  import 'drizzle-orm/sqlite-proxy';
28
28
  import 'use-immer';
@@ -74,4 +74,4 @@ const models = {
74
74
  };
75
75
 
76
76
  export { models };
77
- //# sourceMappingURL=seed.schema.config-miFErQ6h.js.map
77
+ //# sourceMappingURL=seed.schema.config-dylVDX7W.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"seed.schema.config-miFErQ6h.js","sources":["../../src/shared/configs/seed.schema.config.ts"],"sourcesContent":["import { Model, Text } from '@/browser'\n\n@Model\nclass Seed {\n @Text() uid!: string\n @Text() type!: string\n}\n\n@Model\nclass Version {\n @Text() seedUid!: string\n @Text() note!: string\n}\n\n@Model\nclass Metadata {\n @Text() key!: string\n @Text() value!: string\n}\n\nexport const models = {\n Seed,\n Version,\n Metadata,\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,IAAM,IAAI,GAAV,MAAM,IAAI,CAAA;CAGT;AAFS,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAa,CAAA,EAAA,IAAA,CAAA,SAAA,EAAA,KAAA,EAAA,KAAA,CAAA,CAAA;AACZ,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAc,CAAA,EAAA,IAAA,CAAA,SAAA,EAAA,MAAA,EAAA,KAAA,CAAA,CAAA;AAFjB,IAAI,GAAA,UAAA,CAAA;IADT;AACK,CAAA,EAAA,IAAI,CAGT;AAGD,IAAM,OAAO,GAAb,MAAM,OAAO,CAAA;CAGZ;AAFS,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAiB,CAAA,EAAA,OAAA,CAAA,SAAA,EAAA,SAAA,EAAA,KAAA,CAAA,CAAA;AAChB,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAc,CAAA,EAAA,OAAA,CAAA,SAAA,EAAA,MAAA,EAAA,KAAA,CAAA,CAAA;AAFjB,OAAO,GAAA,UAAA,CAAA;IADZ;AACK,CAAA,EAAA,OAAO,CAGZ;AAGD,IAAM,QAAQ,GAAd,MAAM,QAAQ,CAAA;CAGb;AAFS,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAa,CAAA,EAAA,QAAA,CAAA,SAAA,EAAA,KAAA,EAAA,KAAA,CAAA,CAAA;AACZ,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAe,CAAA,EAAA,QAAA,CAAA,SAAA,EAAA,OAAA,EAAA,KAAA,CAAA,CAAA;AAFlB,QAAQ,GAAA,UAAA,CAAA;IADb;AACK,CAAA,EAAA,QAAQ,CAGb;AAEY,MAAA,MAAM,GAAG;IACpB,IAAI;IACJ,OAAO;IACP,QAAQ;;;;;"}
1
+ {"version":3,"file":"seed.schema.config-dylVDX7W.js","sources":["../../src/shared/configs/seed.schema.config.ts"],"sourcesContent":["import { Model, Text } from '@/browser'\n\n@Model\nclass Seed {\n @Text() uid!: string\n @Text() type!: string\n}\n\n@Model\nclass Version {\n @Text() seedUid!: string\n @Text() note!: string\n}\n\n@Model\nclass Metadata {\n @Text() key!: string\n @Text() value!: string\n}\n\nexport const models = {\n Seed,\n Version,\n Metadata,\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,IAAM,IAAI,GAAV,MAAM,IAAI,CAAA;CAGT;AAFS,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAa,CAAA,EAAA,IAAA,CAAA,SAAA,EAAA,KAAA,EAAA,KAAA,CAAA,CAAA;AACZ,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAc,CAAA,EAAA,IAAA,CAAA,SAAA,EAAA,MAAA,EAAA,KAAA,CAAA,CAAA;AAFjB,IAAI,GAAA,UAAA,CAAA;IADT;AACK,CAAA,EAAA,IAAI,CAGT;AAGD,IAAM,OAAO,GAAb,MAAM,OAAO,CAAA;CAGZ;AAFS,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAiB,CAAA,EAAA,OAAA,CAAA,SAAA,EAAA,SAAA,EAAA,KAAA,CAAA,CAAA;AAChB,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAc,CAAA,EAAA,OAAA,CAAA,SAAA,EAAA,MAAA,EAAA,KAAA,CAAA,CAAA;AAFjB,OAAO,GAAA,UAAA,CAAA;IADZ;AACK,CAAA,EAAA,OAAO,CAGZ;AAGD,IAAM,QAAQ,GAAd,MAAM,QAAQ,CAAA;CAGb;AAFS,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAa,CAAA,EAAA,QAAA,CAAA,SAAA,EAAA,KAAA,EAAA,KAAA,CAAA,CAAA;AACZ,UAAA,CAAA;AAAP,IAAA,IAAI,EAAE;;AAAe,CAAA,EAAA,QAAA,CAAA,SAAA,EAAA,OAAA,EAAA,KAAA,CAAA,CAAA;AAFlB,QAAQ,GAAA,UAAA,CAAA;IADb;AACK,CAAA,EAAA,QAAQ,CAGb;AAEY,MAAA,MAAM,GAAG;IACpB,IAAI;IACJ,OAAO;IACP,QAAQ;;;;;"}
@@ -16,6 +16,10 @@ export const createMetadata: CreateMetadata = async (
16
16
 
17
17
  metadataValues.localId = generateId()
18
18
 
19
+ if (!metadataValues.modelType && metadataValues.modelName) {
20
+ metadataValues.modelType = metadataValues.modelName.toLowerCase()
21
+ }
22
+
19
23
  if (
20
24
  propertyRecordSchema &&
21
25
  propertyRecordSchema.localStorageDir &&
@@ -54,6 +54,8 @@ export const getItemsData: GetItemsData = async ({
54
54
  versionsCount: versionData.versionsCount,
55
55
  lastVersionPublishedAt: versionData.lastVersionPublishedAt,
56
56
  lastLocalUpdateAt: versionData.lastLocalUpdateAt,
57
+ latestVersionUid: versionData.latestVersionUid,
58
+ latestVersionLocalId: versionData.latestVersionLocalId,
57
59
  createdAt: seeds.createdAt,
58
60
  })
59
61
  .from(seeds)
@@ -3,7 +3,7 @@ import { versions, VersionsType } from '@/shared/seedSchema'
3
3
  import { and, eq } from 'drizzle-orm'
4
4
 
5
5
  type GetVersionDataProps = {
6
- localId?: string
6
+ localId?: string | null
7
7
  uid?: string
8
8
  seedLocalId?: string
9
9
  }
@@ -195,7 +195,15 @@ export const hydrateFromDb = fromCallback<EventObject, typeof propertyMachine>(
195
195
  }
196
196
 
197
197
  if (urlNeedsToBeRefreshed) {
198
- const filePath = `/files/${localStorageDir}/${refResolvedValue}`
198
+ let dir = localStorageDir
199
+ if (
200
+ !dir &&
201
+ propertyRecordSchema &&
202
+ propertyRecordSchema.refValueType === 'ImageSrc'
203
+ ) {
204
+ dir = 'images'
205
+ }
206
+ const filePath = `/files/${dir}/${refResolvedValue}`
199
207
  const fileExists = await fs.promises.exists(filePath)
200
208
  if (fileExists) {
201
209
  const fileContents = await fs.promises.readFile(filePath)
@@ -214,6 +222,25 @@ export const hydrateFromDb = fromCallback<EventObject, typeof propertyMachine>(
214
222
  propertyValueProcessed = propertyValueFromDb.split(',')
215
223
  }
216
224
 
225
+ if (seedLocalIdFromDb === 'sAFXuO7Uez') {
226
+ console.log(`[hydrateFromDb] sending updateContext with:`, {
227
+ type: 'updateContext',
228
+ localId,
229
+ uid,
230
+ propertyValue: propertyValueProcessed,
231
+ seedLocalId: seedLocalIdFromDb,
232
+ seedUid: seedUidFromDb,
233
+ versionLocalId: versionLocalIdFromDb,
234
+ versionUid: versionUidFromDb,
235
+ schemaUid: schemaUidFromDb,
236
+ refValueType,
237
+ localStorageDir,
238
+ resolvedValue: refResolvedValue,
239
+ resolvedDisplayValue: refResolvedDisplayValue,
240
+ renderValue: refResolvedDisplayValue,
241
+ })
242
+ }
243
+
217
244
  sendBack({
218
245
  type: 'updateContext',
219
246
  localId,
package/dist/src/index.ts CHANGED
@@ -1,21 +1,106 @@
1
- import { setup } from 'xstate'
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { FromCallbackInput } from '@/types/machines'
2
3
  import {
3
- uploadBinaryData,
4
- uploadMetadata,
5
- } from '@/browser/schema/file/upload/actors'
6
-
7
- export const uploadMachine = setup({
8
- actors: {
9
- uploadBinaryData,
10
- uploadMetadata,
11
- },
12
- }).createMachine({
13
- id: 'upload',
14
- initial: 'idle',
15
- context: {
16
- file: '',
17
- },
18
- states: {
19
- idle: {},
20
- },
4
+ ItemPropertyValueType,
5
+ PropertyMachineContext,
6
+ SaveValueToDbEvent,
7
+ } from '@/types/property'
8
+ import { updateItemPropertyValue } from '@/browser/db/write/updateItemPropertyValue'
9
+
10
+ export * from './saveImageSrc'
11
+ export * from './saveRelation'
12
+ export * from './saveItemStorage'
13
+
14
+ export const analyzeInput = fromCallback<
15
+ EventObject,
16
+ FromCallbackInput<PropertyMachineContext, SaveValueToDbEvent>
17
+ >(({ sendBack, input: { context, event } }) => {
18
+ const {
19
+ localId,
20
+ propertyName: propertyNameRaw,
21
+ seedLocalId,
22
+ versionLocalId,
23
+ versionUid,
24
+ propertyValue: existingValue,
25
+ propertyRecordSchema,
26
+ itemModelName,
27
+ schemaUid,
28
+ } = context
29
+
30
+ let newValue: ItemPropertyValueType
31
+
32
+ if (event) {
33
+ newValue = event.newValue
34
+ }
35
+
36
+ if (existingValue === newValue) {
37
+ sendBack({ type: 'saveValueToDbSuccess' })
38
+ return
39
+ }
40
+
41
+ if (!propertyRecordSchema) {
42
+ throw new Error('Missing propertyRecordSchema')
43
+ }
44
+
45
+ const _analyzeInput = async (): Promise<boolean> => {
46
+ let propertyName = propertyNameRaw
47
+
48
+ if (
49
+ propertyRecordSchema.refValueType &&
50
+ propertyRecordSchema.refValueType !== 'ImageSrc' &&
51
+ propertyRecordSchema.dataType === 'Relation'
52
+ ) {
53
+ sendBack({
54
+ type: 'saveRelation',
55
+ newValue,
56
+ })
57
+ return false
58
+ }
59
+
60
+ if (
61
+ propertyRecordSchema.refValueType === 'ImageSrc' ||
62
+ propertyRecordSchema.dataType === 'ImageSrc'
63
+ ) {
64
+ sendBack({
65
+ type: 'saveImageSrc',
66
+ newValue,
67
+ })
68
+ return false
69
+ }
70
+
71
+ if (
72
+ propertyRecordSchema.storageType &&
73
+ propertyRecordSchema.storageType === 'ItemStorage'
74
+ ) {
75
+ sendBack({
76
+ type: 'saveItemStorage',
77
+ newValue,
78
+ })
79
+ return false
80
+ }
81
+
82
+ await updateItemPropertyValue({
83
+ localId: localId,
84
+ propertyName,
85
+ newValue,
86
+ seedLocalId,
87
+ versionLocalId,
88
+ versionUid,
89
+ modelName: itemModelName,
90
+ schemaUid,
91
+ })
92
+
93
+ sendBack({
94
+ type: 'updateContext',
95
+ propertyValue: newValue,
96
+ })
97
+
98
+ return true
99
+ }
100
+
101
+ _analyzeInput().then((isDone) => {
102
+ if (isDone) {
103
+ sendBack({ type: 'saveValueToDbSuccess' })
104
+ }
105
+ })
21
106
  })
@@ -64,6 +64,12 @@ export const propertyMachine = setup({
64
64
  actions: assign(({ context, event }) => {
65
65
  const newContext = Object.assign({}, context)
66
66
 
67
+ if (context.seedLocalId === 'qpIzW1e52r') {
68
+ console.log(
69
+ `[updateContext] before update versionLocalId is ${context.versionLocalId}`,
70
+ )
71
+ }
72
+
67
73
  for (let i = 0; i < Object.keys(event).length; i++) {
68
74
  const key = Object.keys(event)[i]
69
75
  if (key === 'type') {
@@ -71,6 +77,12 @@ export const propertyMachine = setup({
71
77
  }
72
78
  newContext[key] = event[key]
73
79
  }
80
+
81
+ if (context.seedLocalId === 'qpIzW1e52r') {
82
+ console.log(
83
+ `[updateContext] after update versionLocalId is ${newContext.versionLocalId}`,
84
+ )
85
+ }
74
86
  return newContext
75
87
  }),
76
88
  },
@@ -5,12 +5,13 @@ import {
5
5
  PropertyMachineContext,
6
6
  SaveValueToDbEvent,
7
7
  } from '@/types/property'
8
- import { createSeed, updateItemPropertyValue } from '@/browser/db/write'
8
+ import { createSeed } from '@/browser/db/write'
9
9
  import { getDataTypeFromString, getMimeType } from '@/shared/helpers'
10
10
  import { createVersion } from '@/browser/db/write/createVersion'
11
11
  import { fs } from '@zenfs/core'
12
12
  import { getContentUrlFromPath } from '@/browser/helpers'
13
13
  import { createMetadata } from '@/browser/db/write/createMetadata'
14
+ import { updateItemPropertyValue } from '@/browser/db/write/updateItemPropertyValue'
14
15
 
15
16
  const readFileAsDataUrl = async (file: File): Promise<string> => {
16
17
  return new Promise((resolve) => {
@@ -77,6 +78,10 @@ export const saveImageSrc = fromCallback<
77
78
  schemaUid,
78
79
  } = context
79
80
 
81
+ if (seedLocalId === 'qpIzW1e52r') {
82
+ console.log(`[saveImageSrc] versionLocaId is : ${versionLocalId}`)
83
+ }
84
+
80
85
  let newValue: ItemPropertyValueType
81
86
 
82
87
  if (event) {
@@ -173,6 +178,8 @@ export const saveImageSrc = fromCallback<
173
178
  refSeedType: 'image',
174
179
  refResolvedDisplayValue,
175
180
  refResolvedValue: fileName,
181
+ localStorageDir: '/images',
182
+ easDataType: 'bytes32',
176
183
  },
177
184
  propertyRecordSchema,
178
185
  )
@@ -180,7 +187,7 @@ export const saveImageSrc = fromCallback<
180
187
 
181
188
  if (localId) {
182
189
  await updateItemPropertyValue({
183
- propertyLocalId: localId,
190
+ localId: localId,
184
191
  propertyName: propertyNameRaw,
185
192
  newValue: newImageSeedLocalId,
186
193
  seedLocalId,
@@ -190,6 +197,8 @@ export const saveImageSrc = fromCallback<
190
197
  refSeedType: 'image',
191
198
  refResolvedDisplayValue,
192
199
  refResolvedValue: fileName,
200
+ localStorageDir: '/images',
201
+ easDataType: 'bytes32',
193
202
  })
194
203
  }
195
204
 
@@ -0,0 +1,230 @@
1
+ import { escapeSqliteString } from '@/shared/helpers/db'
2
+ import { getAppDb, runQueryForStatement } from '@/browser'
3
+ import { metadata, MetadataType } from '@/shared/seedSchema'
4
+ import { and, eq, sql } from 'drizzle-orm'
5
+ import { getSeedData } from '@/browser/db/read/getSeedData'
6
+ import { getVersionData } from '@/browser/db/read/getVersionData'
7
+ import { generateId } from '@/shared/helpers'
8
+ import debug from 'debug'
9
+ import { eventEmitter } from '@/eventBus'
10
+
11
+ const logger = debug('app:write:updateItemPropertyValue')
12
+
13
+ const sendItemUpdateEvent = ({ modelName, seedLocalId, seedUid }) => {
14
+ if (!modelName || (!seedLocalId && !seedUid)) {
15
+ return
16
+ }
17
+ eventEmitter.emit(`item.${modelName}.${seedUid || seedLocalId}.update`)
18
+ }
19
+
20
+ type UpdateItemPropertyValue = (props: Partial<MetadataType>) => Promise<void>
21
+
22
+ export const updateItemPropertyValue: UpdateItemPropertyValue = async ({
23
+ localId,
24
+ propertyName,
25
+ newValue,
26
+ seedUid,
27
+ seedLocalId,
28
+ modelName,
29
+ refSeedType,
30
+ refResolvedValue,
31
+ refResolvedDisplayValue,
32
+ versionLocalId,
33
+ versionUid,
34
+ schemaUid,
35
+ localStorageDir,
36
+ }) => {
37
+ if (!localId && !seedLocalId) {
38
+ logger(
39
+ `[db/write] [updateItemPropertyValue] no propertyLocalId or seedLocalId for property: ${propertyName}`,
40
+ )
41
+ return
42
+ }
43
+
44
+ let safeNewValue = newValue
45
+
46
+ if (
47
+ typeof newValue === 'string' &&
48
+ !refResolvedDisplayValue &&
49
+ !refResolvedValue
50
+ ) {
51
+ safeNewValue = escapeSqliteString(newValue)
52
+ }
53
+
54
+ const appDb = getAppDb()
55
+
56
+ const rows = await appDb
57
+ .select()
58
+ .from(metadata)
59
+ .where(
60
+ and(
61
+ eq(metadata.propertyName, propertyName!),
62
+ eq(metadata.seedLocalId, seedLocalId!),
63
+ ),
64
+ )
65
+ .orderBy(sql.raw('COALESCE(attestation_created_at, created_at) DESC'))
66
+
67
+ // const mostRecentRecordStatement = `SELECT local_id,
68
+ // uid,
69
+ // property_name,
70
+ // property_value,
71
+ // model_type,
72
+ // seed_uid,
73
+ // seed_local_id,
74
+ // version_local_id,
75
+ // version_uid,
76
+ // schema_uid,
77
+ // eas_data_type
78
+ // FROM metadata
79
+ // WHERE property_name = '${propertyName}'
80
+ // AND seed_local_id = '${seedLocalId}'
81
+ // ORDER BY COALESCE(attestation_created_at, created_at) DESC;`
82
+ //
83
+ // const { rows } = await runQueryForStatement(mostRecentRecordStatement)
84
+
85
+ if (rows && rows.length > 0) {
86
+ const {
87
+ localId,
88
+ uid,
89
+ propertyName: propertyNameFromDb,
90
+ propertyValue: propertyValueFromDb,
91
+ modelType,
92
+ seedUid,
93
+ seedLocalId: seedLocalIdFromDb,
94
+ versionLocalId,
95
+ versionUid,
96
+ schemaUid,
97
+ easDataType,
98
+ localStorageDir: localStorageDirFromDb,
99
+ refSeedType: refSeedTypeFromDb,
100
+ refResolvedValue: refResolvedValueFromDb,
101
+ refResolvedDisplayValue: refResolvedDisplayValueFromDb,
102
+ } = rows[0]
103
+
104
+ if (
105
+ propertyValueFromDb === newValue &&
106
+ modelType === modelName?.toLowerCase() &&
107
+ refSeedTypeFromDb === refSeedType &&
108
+ refResolvedValueFromDb === refResolvedValue
109
+ ) {
110
+ logger(
111
+ `[db/write] [updateItemPropertyValue] value is the same as most recent record for property: ${propertyNameFromDb}`,
112
+ )
113
+ return
114
+ }
115
+
116
+ // This means we already have a local-only record so we should just update that one
117
+ if (!uid) {
118
+ const updatePropertyStatement = `UPDATE metadata
119
+ SET property_value = '${safeNewValue}',
120
+ ref_seed_type = ${refSeedType ? `'${refSeedType}'` : 'NULL'},
121
+ ref_resolved_value = ${refResolvedValue ? `'${refResolvedValue}'` : 'NULL'},
122
+ ref_resolved_display_value = ${refResolvedDisplayValue ? `'${refResolvedDisplayValue}'` : 'NULL'},
123
+ updated_at = ${Date.now()}
124
+ WHERE local_id = '${localId}';`
125
+
126
+ await runQueryForStatement(updatePropertyStatement)
127
+
128
+ sendItemUpdateEvent({ modelName, seedLocalId, seedUid })
129
+
130
+ return
131
+ }
132
+
133
+ const seedDataFromDb = await getSeedData({ seedLocalId })
134
+ const versionDataFromDb = await getVersionData({ localId: versionLocalId })
135
+
136
+ // Here we don't have a local-only record so we need to create a new one
137
+ const newLocalId = generateId()
138
+
139
+ const newPropertyStatement = `INSERT INTO metadata (local_id,
140
+ property_name,
141
+ property_value,
142
+ model_type,
143
+ seed_uid,
144
+ seed_local_id,
145
+ version_local_id,
146
+ version_uid,
147
+ schema_uid,
148
+ eas_data_type,
149
+ ref_seed_type,
150
+ ref_resolved_value,
151
+ ref_resolved_display_value,
152
+ local_storage_dir,
153
+ created_at)
154
+ VALUES ('${newLocalId}',
155
+ '${propertyNameFromDb}',
156
+ '${safeNewValue}',
157
+ '${modelType || modelName?.toLowerCase()}',
158
+ ${seedDataFromDb?.uid ? `'${seedDataFromDb.uid}'` : 'NULL'},
159
+ '${seedLocalIdFromDb}',
160
+ '${versionLocalId}',
161
+ ${versionDataFromDb?.uid ? `'${versionDataFromDb.uid}'` : 'NULL'},
162
+ '${schemaUid}',
163
+ ${easDataType ? `'${easDataType}'` : 'NULL'},
164
+ ${refSeedType ? `'${refSeedType}'` : 'NULL'},
165
+ ${refResolvedValue ? `'${refResolvedValue}'` : 'NULL'},
166
+ ${refResolvedDisplayValue ? `'${refResolvedDisplayValue}'` : 'NULL'},
167
+ ${localStorageDir ? `'${localStorageDir}'` : 'NULL'},
168
+ ${Date.now()});`
169
+
170
+ await runQueryForStatement(newPropertyStatement)
171
+
172
+ sendItemUpdateEvent({ modelName, seedLocalId, seedUid })
173
+
174
+ return
175
+ }
176
+
177
+ // Here there are no records for this property on this seed so we should create one
178
+
179
+ const newLocalId = generateId()
180
+
181
+ if (!seedUid) {
182
+ const seedData = await getSeedData({ seedLocalId })
183
+ if (seedData) {
184
+ seedUid = seedData.uid
185
+ }
186
+ }
187
+
188
+ if (!versionUid) {
189
+ const versionData = await getVersionData({ localId: versionLocalId })
190
+ if (versionData) {
191
+ versionUid = versionData.uid
192
+ }
193
+ }
194
+
195
+ const newPropertyStatement = `INSERT INTO metadata (local_id,
196
+ property_name,
197
+ property_value,
198
+ model_type,
199
+ seed_uid,
200
+ seed_local_id,
201
+ version_local_id,
202
+ version_uid,
203
+ schema_uid,
204
+ ref_seed_type,
205
+ ref_resolved_value,
206
+ ref_resolved_display_value,
207
+ local_storage_dir,
208
+ created_at)
209
+ VALUES ('${newLocalId}',
210
+ '${propertyName}',
211
+ '${safeNewValue}',
212
+ '${modelName?.toLowerCase()}',
213
+ ${seedUid ? `'${seedUid}'` : 'NULL'},
214
+ '${seedLocalId}',
215
+ '${versionLocalId}',
216
+ ${versionUid ? `'${versionUid}'` : 'NULL'},
217
+ '${schemaUid}',
218
+ ${refSeedType ? `'${refSeedType}'` : 'NULL'},
219
+ ${refResolvedValue ? `'${refResolvedValue}'` : 'NULL'},
220
+ ${refResolvedDisplayValue ? `'${refResolvedDisplayValue}'` : 'NULL'},
221
+ ${Date.now()});`
222
+
223
+ await runQueryForStatement(newPropertyStatement)
224
+
225
+ sendItemUpdateEvent({ modelName, seedLocalId, seedUid })
226
+
227
+ if (!seedLocalId && propertyName && modelName && newValue) {
228
+ // TODO: Does this ever happen? If so, what should we do?
229
+ }
230
+ }