@seedprotocol/sdk 0.1.54 → 0.1.56

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 (43) hide show
  1. package/dist/{index-DQKd-s2Q.js → index-Cdz3ZpGp.js} +2164 -1890
  2. package/dist/index-Cdz3ZpGp.js.map +1 -0
  3. package/dist/{index-NmD9sjcJ.js → index-DcYDcCt6.js} +3 -3
  4. package/dist/index-DcYDcCt6.js.map +1 -0
  5. package/dist/main.js +2 -2
  6. package/dist/{seed.schema.config-OyHsE0Zl.js → seed.schema.config-BjnTnTUw.js} +2 -2
  7. package/dist/{seed.schema.config-OyHsE0Zl.js.map → seed.schema.config-BjnTnTUw.js.map} +1 -1
  8. package/dist/src/createMetadata.ts +1 -1
  9. package/dist/src/download.ts +6 -2
  10. package/dist/src/getItemProperty.ts +0 -1
  11. package/dist/src/propertyMachine.ts +62 -16
  12. package/dist/src/resolveRelatedValue.ts +4 -0
  13. package/dist/src/saveImageSrc.ts +201 -0
  14. package/dist/src/saveItemStorage.ts +145 -0
  15. package/dist/src/saveRelation.ts +112 -0
  16. package/dist/src/write.ts +27 -7
  17. package/dist/types/src/browser/db/read/getItemProperty.d.ts.map +1 -1
  18. package/dist/types/src/browser/db/write.d.ts.map +1 -1
  19. package/dist/types/src/browser/events/files/download.d.ts.map +1 -1
  20. package/dist/types/src/browser/item/Item.d.ts.map +1 -1
  21. package/dist/types/src/browser/property/ItemProperty.d.ts +20 -11
  22. package/dist/types/src/browser/property/ItemProperty.d.ts.map +1 -1
  23. package/dist/types/src/browser/property/actors/resolveRelatedValue.d.ts.map +1 -1
  24. package/dist/types/src/browser/property/actors/saveValueToDb/index.d.ts +8 -0
  25. package/dist/types/src/browser/property/actors/saveValueToDb/index.d.ts.map +1 -0
  26. package/dist/types/src/browser/property/actors/saveValueToDb/saveImageSrc.d.ts +5 -0
  27. package/dist/types/src/browser/property/actors/saveValueToDb/saveImageSrc.d.ts.map +1 -0
  28. package/dist/types/src/browser/property/actors/saveValueToDb/saveItemStorage.d.ts +5 -0
  29. package/dist/types/src/browser/property/actors/saveValueToDb/saveItemStorage.d.ts.map +1 -0
  30. package/dist/types/src/browser/property/actors/saveValueToDb/saveRelation.d.ts +5 -0
  31. package/dist/types/src/browser/property/actors/saveValueToDb/saveRelation.d.ts.map +1 -0
  32. package/dist/types/src/browser/property/propertyMachine.d.ts.map +1 -1
  33. package/dist/types/src/browser/schema/file/fetchAll/actors.d.ts.map +1 -1
  34. package/dist/types/src/shared/helpers/index.d.ts +1 -1
  35. package/dist/types/src/shared/helpers/index.d.ts.map +1 -1
  36. package/dist/types/src/types/property.d.ts +6 -0
  37. package/dist/types/src/types/property.d.ts.map +1 -1
  38. package/package.json +1 -1
  39. package/dist/index-DQKd-s2Q.js.map +0 -1
  40. package/dist/index-NmD9sjcJ.js.map +0 -1
  41. package/dist/src/saveValueToDb.ts +0 -208
  42. package/dist/types/src/browser/property/actors/saveValueToDb.d.ts +0 -10
  43. package/dist/types/src/browser/property/actors/saveValueToDb.d.ts.map +0 -1
@@ -1,4 +1,4 @@
1
- export { f as GET_ALL_PROPERTIES_FOR_ALL_VERSIONS, e as GET_PROPERTIES, G as GET_SCHEMAS, a as GET_SEEDS, b as GET_SEED_IDS, c as GET_STORAGE_TRANSACTION_ID, d as GET_VERSIONS, I as Item, g as itemMachineAll, i as itemMachineSingle } from './index-DQKd-s2Q.js';
1
+ export { f as GET_ALL_PROPERTIES_FOR_ALL_VERSIONS, e as GET_PROPERTIES, G as GET_SCHEMAS, a as GET_SEEDS, b as GET_SEED_IDS, c as GET_STORAGE_TRANSACTION_ID, d as GET_VERSIONS, I as Item, g as itemMachineAll, i as itemMachineSingle } from './index-Cdz3ZpGp.js';
2
2
  import './constants-BLctWkrn.js';
3
3
  import 'path';
4
4
  import 'reflect-metadata';
@@ -17,6 +17,7 @@ import '@tanstack/react-query';
17
17
  import 'graphql-request';
18
18
  import '@tanstack/query-sync-storage-persister';
19
19
  import '@tanstack/react-query-persist-client';
20
+ import 'react';
20
21
  import 'rxjs';
21
22
  import 'immer';
22
23
  import 'pluralize';
@@ -24,7 +25,6 @@ import '@statelyai/inspect';
24
25
  import 'drizzle-orm/sqlite-proxy';
25
26
  import '@zenfs/dom';
26
27
  import 'arweave';
27
- import 'react';
28
28
  import 'use-immer';
29
29
  import '@xstate/react';
30
- //# sourceMappingURL=index-NmD9sjcJ.js.map
30
+ //# sourceMappingURL=index-DcYDcCt6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DcYDcCt6.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
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-DQKd-s2Q.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-Cdz3ZpGp.js';
2
2
  import 'immer';
3
3
  import 'reflect-metadata';
4
4
  import './constants-BLctWkrn.js';
@@ -19,12 +19,12 @@ import '@tanstack/react-query';
19
19
  import 'graphql-request';
20
20
  import '@tanstack/query-sync-storage-persister';
21
21
  import '@tanstack/react-query-persist-client';
22
+ import 'react';
22
23
  import 'rxjs';
23
24
  import 'pluralize';
24
25
  import '@statelyai/inspect';
25
26
  import 'drizzle-orm/sqlite-proxy';
26
27
  import '@zenfs/dom';
27
- import 'react';
28
28
  import 'use-immer';
29
29
  import '@xstate/react';
30
30
  //# sourceMappingURL=main.js.map
@@ -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-DQKd-s2Q.js';
3
+ import { T as Text, M as Model } from './index-Cdz3ZpGp.js';
4
4
  import 'react';
5
5
  import 'reflect-metadata';
6
6
  import 'xstate';
@@ -74,4 +74,4 @@ const models = {
74
74
  };
75
75
 
76
76
  export { models };
77
- //# sourceMappingURL=seed.schema.config-OyHsE0Zl.js.map
77
+ //# sourceMappingURL=seed.schema.config-BjnTnTUw.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"seed.schema.config-OyHsE0Zl.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-BjnTnTUw.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;;;;;"}
@@ -21,7 +21,7 @@ export const createMetadata: CreateMetadata = async (
21
21
  propertyRecordSchema.localStorageDir &&
22
22
  propertyRecordSchema.storageType === 'ItemStorage'
23
23
  ) {
24
- metadataValues.refResolvedValue = `${metadataValues.localId}${propertyRecordSchema.filenameSuffix}`
24
+ metadataValues.refResolvedValue = `${metadataValues.seedLocalId}${propertyRecordSchema.filenameSuffix}`
25
25
  metadataValues.refValueType = 'file'
26
26
  }
27
27
 
@@ -6,7 +6,11 @@ import { appState } from 'src/shared/seedSchema'
6
6
  import { eq } from 'drizzle-orm'
7
7
  import { getArweave } from '@/browser/schema/file'
8
8
  import { getAddressesFromDb } from '@/shared/helpers/db'
9
- import { getImageDataType, getMimeType, identifyString } from '@/shared/helpers'
9
+ import {
10
+ getDataTypeFromString,
11
+ getMimeType,
12
+ identifyString,
13
+ } from '@/shared/helpers'
10
14
  import { arweaveClient, easClient, queryClient } from '@/browser/helpers'
11
15
  import { GET_FILES_METADATA } from '@/browser/schema/file/queries'
12
16
  import debug from 'debug'
@@ -194,7 +198,7 @@ export const downloadAllFilesBinaryRequestHandler = async () => {
194
198
  contentType !== 'base64' &&
195
199
  contentType !== 'html'
196
200
  ) {
197
- const possibleImageType = getImageDataType(dataString)
201
+ const possibleImageType = getDataTypeFromString(dataString)
198
202
  if (!possibleImageType) {
199
203
  logger(
200
204
  `[fetchAll/actors] [fetchAllBinaryData] transaction ${transactionId} data not in expected format: ${possibleImageType}`,
@@ -17,7 +17,6 @@ export const getItemPropertyData: GetItemPropertyData = async (props) => {
17
17
 
18
18
  for (const [propertyName, propertyValue] of Object.entries(props)) {
19
19
  if (Object.keys(tableColumns).includes(propertyName)) {
20
- const column = tableColumns[propertyName]
21
20
  whereClauses.push(eq(tableColumns[propertyName], propertyValue))
22
21
  }
23
22
  }
@@ -6,12 +6,18 @@ import { waitForDb } from '@/browser/property/actors/waitForDb'
6
6
  import { initialize } from '@/browser/property/actors/initialize'
7
7
  import { resolveRelatedValue } from '@/browser/property/actors/resolveRelatedValue'
8
8
  import { hydrateFromDb } from '@/browser/property/actors/hydrateFromDb'
9
- import { saveValueToDb } from '@/browser/property/actors/saveValueToDb'
9
+ import {
10
+ analyzeInput,
11
+ saveImageSrc,
12
+ saveItemStorage,
13
+ saveRelation,
14
+ } from '@/browser/property/actors/saveValueToDb' // import { updateMachineContext } from '@/browser/helpers'
10
15
  // import { updateMachineContext } from '@/browser/helpers'
11
16
 
12
17
  export const propertyMachine = setup({
13
18
  types: {
14
19
  context: {} as PropertyMachineContext,
20
+ input: {} as PropertyMachineContext,
15
21
  },
16
22
  // actions: {
17
23
  // updateContext: updateMachineContext,
@@ -22,7 +28,10 @@ export const propertyMachine = setup({
22
28
  initialize,
23
29
  resolveRelatedValue,
24
30
  resolveRemoteStorage,
25
- saveValueToDb,
31
+ analyzeInput,
32
+ saveImageSrc,
33
+ saveRelation,
34
+ saveItemStorage,
26
35
  },
27
36
  }).createMachine({
28
37
  id: 'itemProperty',
@@ -136,23 +145,60 @@ export const propertyMachine = setup({
136
145
  },
137
146
  },
138
147
  saving: {
139
- on: {
140
- saveValueToDbSuccess: {
141
- target: 'idle',
142
- actions: assign({
143
- isSaving: false,
144
- }),
148
+ initial: 'analyzingInput',
149
+ states: {
150
+ analyzingInput: {
151
+ on: {
152
+ saveValueToDbSuccess: {
153
+ target: 'doneSaving',
154
+ },
155
+ saveImageSrc: 'savingImageSrc',
156
+ saveRelation: 'savingRelation',
157
+ saveItemStorage: 'savingItemStorage',
158
+ },
159
+ invoke: {
160
+ src: 'analyzeInput',
161
+ input: ({ context, event }) => ({ context, event }),
162
+ },
145
163
  },
146
- saveValueToDbFailure: {
147
- target: 'idle',
148
- actions: assign({
149
- isSaving: false,
150
- }),
164
+ savingImageSrc: {
165
+ on: {
166
+ saveImageSrcSuccess: 'doneSaving',
167
+ },
168
+ invoke: {
169
+ src: 'saveImageSrc',
170
+ input: ({ context, event }) => ({ context, event }),
171
+ },
172
+ },
173
+ savingRelation: {
174
+ on: {
175
+ saveRelationSuccess: 'doneSaving',
176
+ },
177
+ invoke: {
178
+ src: 'saveRelation',
179
+ input: ({ context, event }) => ({ context, event }),
180
+ },
181
+ },
182
+ savingItemStorage: {
183
+ on: {
184
+ saveItemStorageSuccess: 'doneSaving',
185
+ },
186
+ invoke: {
187
+ src: 'saveItemStorage',
188
+ input: ({ context, event }) => ({ context, event }),
189
+ },
190
+ },
191
+ doneSaving: {
192
+ type: 'final',
151
193
  },
152
194
  },
153
- invoke: {
154
- src: 'saveValueToDb',
155
- input: ({ context, event }) => ({ context, event }),
195
+ onDone: {
196
+ target: 'idle',
197
+ actions: assign(({ context }) => {
198
+ return {
199
+ isSaving: false,
200
+ }
201
+ }),
156
202
  },
157
203
  },
158
204
  },
@@ -25,6 +25,10 @@ export const resolveRelatedValue = fromCallback<
25
25
  schemaUid,
26
26
  } = context
27
27
 
28
+ if (seedLocalId === 'AhiILhtcVq') {
29
+ console.log('[resolveRelatedValue] seedLocalId', seedLocalId)
30
+ }
31
+
28
32
  const _resolveRelatedValue = async () => {
29
33
  if (!propertyValue || !isRelation) {
30
34
  return
@@ -0,0 +1,201 @@
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { FromCallbackInput } from '@/types/machines'
3
+ import {
4
+ ItemPropertyValueType,
5
+ PropertyMachineContext,
6
+ SaveValueToDbEvent,
7
+ } from '@/types/property'
8
+ import { createSeed, updateItemPropertyValue } from '@/browser/db/write'
9
+ import { getDataTypeFromString, getMimeType } from '@/shared/helpers'
10
+ import { createVersion } from '@/browser/db/write/createVersion'
11
+ import { fs } from '@zenfs/core'
12
+ import { getContentUrlFromPath } from '@/browser/helpers'
13
+ import { createMetadata } from '@/browser/db/write/createMetadata'
14
+
15
+ const readFileAsDataUrl = async (file: File): Promise<string> => {
16
+ return new Promise((resolve) => {
17
+ const reader = new FileReader()
18
+ reader.onload = async (e) => {
19
+ const base64 = e.target.result.split(',')[1] // Extract the base64 string
20
+ const mimeType = file.type // Get the file's MIME type
21
+ const base64WithMimeType = `data:${mimeType};base64,${base64}`
22
+
23
+ resolve(base64WithMimeType)
24
+ }
25
+
26
+ reader.readAsDataURL(file)
27
+ })
28
+ }
29
+
30
+ const readFileAsArrayBuffer = async (file: File): Promise<ArrayBuffer> => {
31
+ return new Promise((resolve) => {
32
+ const reader = new FileReader()
33
+ reader.onload = async (e) => {
34
+ const arrayBuffer = e.target.result as ArrayBuffer
35
+
36
+ resolve(arrayBuffer)
37
+ }
38
+
39
+ reader.readAsArrayBuffer(file)
40
+ })
41
+ }
42
+
43
+ const fetchImage = async (url: string) => {
44
+ const response = await fetch(url)
45
+ const mimeType = response.headers.get('Content-Type')
46
+ const imageBuffer = await response.arrayBuffer()
47
+ const bytes = new Uint8Array(imageBuffer)
48
+
49
+ const binaryString = bytes.reduce(
50
+ (acc, byte) => acc + String.fromCharCode(byte),
51
+ '',
52
+ )
53
+
54
+ let base64 = btoa(binaryString)
55
+
56
+ if (mimeType) {
57
+ base64 = `data:${mimeType};base64,${base64}`
58
+ }
59
+
60
+ return base64
61
+ }
62
+
63
+ export const saveImageSrc = fromCallback<
64
+ EventObject,
65
+ FromCallbackInput<PropertyMachineContext, SaveValueToDbEvent>
66
+ >(({ sendBack, input: { context, event } }) => {
67
+ const {
68
+ localId,
69
+ propertyName: propertyNameRaw,
70
+ propertyValue: existingValue,
71
+ propertyRecordSchema,
72
+ itemModelName,
73
+ seedLocalId,
74
+ seedUid,
75
+ versionLocalId,
76
+ versionUid,
77
+ schemaUid,
78
+ } = context
79
+
80
+ let newValue: ItemPropertyValueType
81
+
82
+ if (event) {
83
+ newValue = event.newValue
84
+ }
85
+
86
+ if (existingValue === newValue) {
87
+ sendBack({ type: 'saveValueToDbSuccess' })
88
+ return
89
+ }
90
+
91
+ const _saveImageSrc = async (): Promise<void> => {
92
+ let propertyName = propertyNameRaw
93
+
94
+ if (!propertyNameRaw.endsWith('Id')) {
95
+ propertyName = `${propertyName}Id`
96
+ }
97
+
98
+ let newValueType
99
+ let fileData: string | ArrayBuffer | undefined
100
+ let mimeType
101
+ let fileName
102
+
103
+ if (typeof newValue === 'string') {
104
+ newValueType = getDataTypeFromString(newValue)
105
+ }
106
+
107
+ if (newValueType === 'imageBase64') {
108
+ mimeType = getMimeType(newValue as string)
109
+ fileData = newValue as string
110
+ }
111
+
112
+ if (newValueType === 'url') {
113
+ fileData = await fetchImage(newValue as string)
114
+ }
115
+
116
+ if (newValue instanceof File) {
117
+ fileName = newValue.name
118
+ mimeType = newValue.type
119
+ fileData = await readFileAsArrayBuffer(newValue)
120
+ }
121
+
122
+ if (!fileData) {
123
+ throw new Error('No file data found')
124
+ }
125
+
126
+ const newImageSeedLocalId = await createSeed({
127
+ type: 'image',
128
+ })
129
+
130
+ if (!fileName) {
131
+ fileName = newImageSeedLocalId
132
+ if (mimeType) {
133
+ fileName += `.${mimeType.split('/')[1]}`
134
+ }
135
+ }
136
+
137
+ const filePath = `/files/images/${fileName}`
138
+
139
+ const imageVersionLocalId = await createVersion({
140
+ seedLocalId: newImageSeedLocalId,
141
+ seedType: 'image',
142
+ })
143
+
144
+ if (fileData instanceof ArrayBuffer) {
145
+ await fs.promises.writeFile(filePath, new Uint8Array(fileData))
146
+ }
147
+
148
+ if (typeof fileData === 'string') {
149
+ await fs.promises.writeFile(filePath, fileData)
150
+ }
151
+
152
+ const refResolvedDisplayValue = await getContentUrlFromPath(filePath)
153
+
154
+ if (!localId) {
155
+ await createMetadata(
156
+ {
157
+ propertyName,
158
+ propertyValue: newImageSeedLocalId,
159
+ seedLocalId,
160
+ seedUid,
161
+ versionLocalId: imageVersionLocalId,
162
+ versionUid,
163
+ modelName: itemModelName,
164
+ schemaUid,
165
+ refSeedType: 'image',
166
+ refResolvedDisplayValue,
167
+ refResolvedValue: fileName,
168
+ },
169
+ propertyRecordSchema,
170
+ )
171
+ }
172
+
173
+ if (localId) {
174
+ await updateItemPropertyValue({
175
+ propertyLocalId: localId,
176
+ propertyName: propertyNameRaw,
177
+ newValue: newImageSeedLocalId,
178
+ seedLocalId,
179
+ versionLocalId,
180
+ modelName: itemModelName,
181
+ schemaUid,
182
+ refSeedType: 'image',
183
+ refResolvedDisplayValue,
184
+ refResolvedValue: fileName,
185
+ })
186
+ }
187
+
188
+ sendBack({
189
+ type: 'updateContext',
190
+ propertyValue: newImageSeedLocalId,
191
+ refSeedType: 'image',
192
+ renderValue: refResolvedDisplayValue,
193
+ resolvedDisplayValue: refResolvedDisplayValue,
194
+ resolvedValue: fileName,
195
+ })
196
+ }
197
+
198
+ _saveImageSrc().then(() => {
199
+ sendBack({ type: 'saveImageSrcSuccess' })
200
+ })
201
+ })
@@ -0,0 +1,145 @@
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { FromCallbackInput } from '@/types/machines'
3
+ import {
4
+ ItemPropertyValueType,
5
+ PropertyMachineContext,
6
+ SaveValueToDbEvent,
7
+ } from '@/types/property'
8
+ import { getAppDb } from '@/browser'
9
+ import { getItemPropertyData } from '@/browser/db/read/getItemProperty'
10
+ import { getItemDataFromDb } from '@/browser/db/read/getItem'
11
+ import { and, eq } from 'drizzle-orm'
12
+ import { metadata } from '@/shared/seedSchema'
13
+ import { createMetadata } from '@/browser/db/write/createMetadata'
14
+ import { fs } from '@zenfs/core'
15
+
16
+ export const saveItemStorage = fromCallback<
17
+ EventObject,
18
+ FromCallbackInput<PropertyMachineContext, SaveValueToDbEvent>
19
+ >(({ sendBack, input: { context, event } }) => {
20
+ const {
21
+ localId,
22
+ seedLocalId,
23
+ seedUid,
24
+ propertyName,
25
+ propertyRecordSchema,
26
+ itemModelName,
27
+ propertyValue: existingValue,
28
+ } = context
29
+
30
+ if (!propertyRecordSchema) {
31
+ throw new Error('Missing propertyRecordSchema')
32
+ }
33
+
34
+ let newValue: ItemPropertyValueType
35
+
36
+ if (event) {
37
+ newValue = event.newValue
38
+ }
39
+
40
+ if (existingValue === newValue) {
41
+ sendBack({ type: 'saveValueToDbSuccess' })
42
+ return
43
+ }
44
+
45
+ const _saveItemStorage = async (): Promise<boolean> => {
46
+ // Save value to file
47
+ const appDb = getAppDb()
48
+ let propertyData
49
+
50
+ if (localId) {
51
+ propertyData = await getItemPropertyData({
52
+ localId,
53
+ })
54
+ }
55
+
56
+ if (!localId && seedLocalId) {
57
+ const itemData = await getItemDataFromDb({
58
+ seedLocalId,
59
+ })
60
+ if (itemData) {
61
+ const whereClauses = [
62
+ eq(metadata.propertyName, propertyName),
63
+ eq(metadata.seedLocalId, seedLocalId),
64
+ ]
65
+
66
+ if (itemData.latestVersionLocalId) {
67
+ whereClauses.push(
68
+ eq(metadata.versionLocalId, itemData.latestVersionLocalId),
69
+ )
70
+ }
71
+
72
+ const queryRows = await appDb
73
+ .select()
74
+ .from(metadata)
75
+ .where(and(...whereClauses))
76
+
77
+ if (queryRows && queryRows.length) {
78
+ propertyData = queryRows[0]
79
+ }
80
+
81
+ if (!propertyData) {
82
+ const propertyDataRows = await createMetadata(
83
+ {
84
+ propertyName,
85
+ modelType: itemModelName.toLowerCase(),
86
+ seedLocalId,
87
+ seedUid,
88
+ versionLocalId: itemData.latestVersionLocalId,
89
+ versionUid: itemData.latestVersionUid,
90
+ localStorageDir: propertyRecordSchema.localStorageDir,
91
+ refValueType: 'file',
92
+ },
93
+ propertyRecordSchema,
94
+ )
95
+
96
+ propertyData = propertyDataRows[0]
97
+ }
98
+
99
+ // propertyData = {
100
+ // propertyName,
101
+ // seedLocalId,
102
+ // seedUid,
103
+ // versionLocalId: itemData.latestVersionLocalId,
104
+ // versionUid: itemData.latestVersionUid,
105
+ // schemaUid: itemData.schemaUid,
106
+ // }
107
+ }
108
+ }
109
+
110
+ const localStorageDir =
111
+ propertyRecordSchema.localStorageDir || propertyData.localStorageDir
112
+ const fileName =
113
+ propertyData.refResolvedValue ||
114
+ `${propertyData.seedLocalId}${propertyRecordSchema.filenameSuffix}`
115
+
116
+ if (!localStorageDir || !fileName) {
117
+ throw new Error(
118
+ `Missing localStorageDir: ${localStorageDir} or fileName: ${fileName}`,
119
+ )
120
+ }
121
+
122
+ const filePath = `/files/${localStorageDir}/${fileName}`
123
+ await fs.promises.writeFile(filePath, newValue)
124
+
125
+ await appDb
126
+ .update(metadata)
127
+ .set({
128
+ refResolvedValue: fileName,
129
+ })
130
+ .where(eq(metadata.localId, propertyData.localId))
131
+
132
+ sendBack({
133
+ type: 'updateContext',
134
+ renderValue: newValue,
135
+ })
136
+
137
+ return true
138
+ }
139
+
140
+ _saveItemStorage().then((success) => {
141
+ if (success) {
142
+ sendBack({ type: 'saveItemStorageSuccess' })
143
+ }
144
+ })
145
+ })
@@ -0,0 +1,112 @@
1
+ import { EventObject, fromCallback } from 'xstate'
2
+ import { FromCallbackInput } from '@/types/machines'
3
+ import {
4
+ ItemPropertyValueType,
5
+ PropertyMachineContext,
6
+ SaveValueToDbEvent,
7
+ } from '@/types/property'
8
+ import { getDataTypeFromString } from '@/shared/helpers'
9
+
10
+ export const saveRelation = fromCallback<
11
+ EventObject,
12
+ FromCallbackInput<PropertyMachineContext, SaveValueToDbEvent>
13
+ >(({ sendBack, input: { context, event } }) => {
14
+ const {
15
+ localId,
16
+ propertyName: propertyNameRaw,
17
+ versionLocalId,
18
+ seedUid,
19
+ seedLocalId,
20
+ propertyValue: existingValue,
21
+ propertyRecordSchema,
22
+ } = context
23
+
24
+ if (!propertyRecordSchema) {
25
+ throw new Error('Missing propertyRecordSchema')
26
+ }
27
+
28
+ let newValue: ItemPropertyValueType
29
+
30
+ if (event) {
31
+ newValue = event.newValue
32
+ }
33
+
34
+ const _saveRelation = async (): Promise<boolean> => {
35
+ let refResolvedDisplayValue
36
+ let refSeedType
37
+ let propertyName = propertyNameRaw
38
+ let versionLocalIdToSave = versionLocalId
39
+
40
+ const refResolvedValue = newValue
41
+
42
+ if (!propertyName.endsWith('Id')) {
43
+ propertyName = `${propertyName}Id`
44
+ }
45
+
46
+ let newValueType
47
+
48
+ if (typeof newValue === 'string') {
49
+ newValueType = getDataTypeFromString(newValue)
50
+ }
51
+
52
+ if (newValue instanceof File) {
53
+ newValueType = 'file'
54
+ }
55
+
56
+ if (propertyRecordSchema.dataType === 'ImageSrc') {
57
+ sendBack({
58
+ type: 'saveImageSrc',
59
+ newValue,
60
+ newValueType,
61
+ })
62
+ return false
63
+ }
64
+
65
+ return true
66
+
67
+ // let fileType
68
+ //
69
+ // const dirs = await fs.promises.readdir('/files')
70
+ //
71
+ // for (const dir of dirs) {
72
+ // const files = await fs.promises.readdir(`/files/${dir}`)
73
+ // if (newValue && files.includes(newValue as string)) {
74
+ // fileType = dir
75
+ // break
76
+ // }
77
+ // }
78
+ //
79
+ // if (newValue && fileType === 'images') {
80
+ // const filePath = `/files/images/${newValue}`
81
+ // refResolvedDisplayValue = await getContentUrlFromPath(filePath)
82
+ // refSeedType = 'image'
83
+ // newValue = await createSeed({
84
+ // type: refSeedType,
85
+ // })
86
+ // await createVersion({
87
+ // seedLocalId,
88
+ // seedUid,
89
+ // seedType: refSeedType,
90
+ // })
91
+ // }
92
+ //
93
+ // await updateItemPropertyValue({
94
+ // propertyLocalId: localId,
95
+ // propertyName,
96
+ // newValue,
97
+ // seedLocalId,
98
+ // refSeedType,
99
+ // refResolvedValue,
100
+ // refResolvedDisplayValue,
101
+ // versionLocalId,
102
+ // modelName: itemModelName,
103
+ // schemaUid,
104
+ // })
105
+ }
106
+
107
+ _saveRelation().then((isDone) => {
108
+ if (isDone) {
109
+ sendBack({ type: 'saveRelationSuccess' })
110
+ }
111
+ })
112
+ })