@seedprotocol/sdk 0.1.53 → 0.1.55
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.
- package/dist/{index-5a9z-kqT.js → index-BkzKfVvD.js} +3 -3
- package/dist/index-BkzKfVvD.js.map +1 -0
- package/dist/{index-DcXK4ERW.js → index-D4my8yy8.js} +1493 -1079
- package/dist/index-D4my8yy8.js.map +1 -0
- package/dist/main.js +2 -2
- package/dist/{seed.schema.config-BtfzZOfM.js → seed.schema.config-BHZSMMmL.js} +2 -2
- package/dist/{seed.schema.config-BtfzZOfM.js.map → seed.schema.config-BHZSMMmL.js.map} +1 -1
- package/dist/src/ItemProperty.ts +114 -68
- package/dist/src/createMetadata.ts +36 -0
- package/dist/src/download.ts +6 -2
- package/dist/src/getItem.ts +12 -37
- package/dist/src/getItemProperty.ts +34 -0
- package/dist/src/getItems.ts +11 -18
- package/dist/src/getVersionData.ts +36 -48
- package/dist/src/hydrateFromDb.ts +11 -15
- package/dist/src/propertyMachine.ts +80 -18
- package/dist/src/resolveRelatedValue.ts +4 -0
- package/dist/src/saveImageSrc.ts +200 -0
- package/dist/src/saveItemStorage.ts +145 -0
- package/dist/src/saveRelation.ts +112 -0
- package/dist/src/syncDbWithEas.ts +1 -1
- package/dist/src/versionData.ts +24 -0
- package/dist/src/write.ts +27 -7
- package/dist/types/src/browser/db/read/getItem.d.ts.map +1 -1
- package/dist/types/src/browser/db/read/getItemProperty.d.ts +6 -0
- package/dist/types/src/browser/db/read/getItemProperty.d.ts.map +1 -0
- package/dist/types/src/browser/db/read/getItems.d.ts.map +1 -1
- package/dist/types/src/browser/db/read/getVersionData.d.ts +5 -14
- package/dist/types/src/browser/db/read/getVersionData.d.ts.map +1 -1
- package/dist/types/src/browser/db/read/subqueries/versionData.d.ts +70 -0
- package/dist/types/src/browser/db/read/subqueries/versionData.d.ts.map +1 -0
- package/dist/types/src/browser/db/write/createMetadata.d.ts +6 -0
- package/dist/types/src/browser/db/write/createMetadata.d.ts.map +1 -0
- package/dist/types/src/browser/db/write.d.ts.map +1 -1
- package/dist/types/src/browser/events/files/download.d.ts.map +1 -1
- package/dist/types/src/browser/item/Item.d.ts +1 -7
- package/dist/types/src/browser/item/Item.d.ts.map +1 -1
- package/dist/types/src/browser/property/ItemProperty.d.ts +24 -8
- package/dist/types/src/browser/property/ItemProperty.d.ts.map +1 -1
- package/dist/types/src/browser/property/actors/hydrateFromDb.d.ts.map +1 -1
- package/dist/types/src/browser/property/actors/resolveRelatedValue.d.ts.map +1 -1
- package/dist/types/src/browser/property/actors/saveValueToDb/index.d.ts +8 -0
- package/dist/types/src/browser/property/actors/saveValueToDb/index.d.ts.map +1 -0
- package/dist/types/src/browser/property/actors/saveValueToDb/saveImageSrc.d.ts +5 -0
- package/dist/types/src/browser/property/actors/saveValueToDb/saveImageSrc.d.ts.map +1 -0
- package/dist/types/src/browser/property/actors/saveValueToDb/saveItemStorage.d.ts +5 -0
- package/dist/types/src/browser/property/actors/saveValueToDb/saveItemStorage.d.ts.map +1 -0
- package/dist/types/src/browser/property/actors/saveValueToDb/saveRelation.d.ts +5 -0
- package/dist/types/src/browser/property/actors/saveValueToDb/saveRelation.d.ts.map +1 -0
- package/dist/types/src/browser/property/index.d.ts +9 -9
- package/dist/types/src/browser/property/propertyMachine.d.ts.map +1 -1
- package/dist/types/src/browser/schema/file/fetchAll/actors.d.ts.map +1 -1
- package/dist/types/src/shared/helpers/index.d.ts +1 -1
- package/dist/types/src/shared/helpers/index.d.ts.map +1 -1
- package/dist/types/src/types/item.d.ts +17 -0
- package/dist/types/src/types/item.d.ts.map +1 -1
- package/dist/types/src/types/property.d.ts +15 -0
- package/dist/types/src/types/property.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/index-5a9z-kqT.js.map +0 -1
- package/dist/index-DcXK4ERW.js.map +0 -1
- package/dist/src/saveValueToDb.ts +0 -94
- package/dist/types/src/browser/property/actors/saveValueToDb.d.ts +0 -2
- package/dist/types/src/browser/property/actors/saveValueToDb.d.ts.map +0 -1
|
@@ -81,19 +81,7 @@ export const hydrateFromDb = fromCallback<EventObject, typeof propertyMachine>(
|
|
|
81
81
|
)
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
const selectFromStatement = db
|
|
85
|
-
.select({
|
|
86
|
-
localId: metadata.localId,
|
|
87
|
-
uid: metadata.uid,
|
|
88
|
-
propertyName: metadata.propertyName,
|
|
89
|
-
propertyValue: metadata.propertyValue,
|
|
90
|
-
seedLocalId: metadata.seedLocalId,
|
|
91
|
-
seedUid: metadata.seedUid,
|
|
92
|
-
schemaUid: metadata.schemaUid,
|
|
93
|
-
refResolvedValue: metadata.refResolvedValue,
|
|
94
|
-
refResolvedDisplayValue: metadata.refResolvedDisplayValue,
|
|
95
|
-
})
|
|
96
|
-
.from(metadata)
|
|
84
|
+
const selectFromStatement = db.select().from(metadata)
|
|
97
85
|
|
|
98
86
|
if (seedUid && !seedLocalId) {
|
|
99
87
|
hydrateQuery = selectFromStatement.where(
|
|
@@ -139,8 +127,12 @@ export const hydrateFromDb = fromCallback<EventObject, typeof propertyMachine>(
|
|
|
139
127
|
seedLocalId: seedLocalIdFromDb,
|
|
140
128
|
seedUid: seedUidFromDb,
|
|
141
129
|
schemaUid: schemaUidFromDb,
|
|
130
|
+
versionLocalId: versionLocalIdFromDb,
|
|
131
|
+
versionUid: versionUidFromDb,
|
|
132
|
+
refValueType,
|
|
142
133
|
refResolvedValue,
|
|
143
134
|
refResolvedDisplayValue,
|
|
135
|
+
localStorageDir,
|
|
144
136
|
} = firstRow
|
|
145
137
|
|
|
146
138
|
if (propertyName && !propertyNameFromDb) {
|
|
@@ -186,9 +178,13 @@ export const hydrateFromDb = fromCallback<EventObject, typeof propertyMachine>(
|
|
|
186
178
|
propertyValue: propertyValueFromDb,
|
|
187
179
|
seedLocalId: seedLocalIdFromDb,
|
|
188
180
|
seedUid: seedUidFromDb,
|
|
181
|
+
versionLocalId: versionLocalIdFromDb,
|
|
182
|
+
versionUid: versionUidFromDb,
|
|
189
183
|
schemaUid: schemaUidFromDb,
|
|
190
|
-
|
|
191
|
-
|
|
184
|
+
refValueType,
|
|
185
|
+
localStorageDir,
|
|
186
|
+
resolvedValue: refResolvedValue,
|
|
187
|
+
resolvedDisplayValue: refResolvedDisplayValue,
|
|
192
188
|
renderValue: refResolvedDisplayValue,
|
|
193
189
|
})
|
|
194
190
|
|
|
@@ -6,20 +6,32 @@ 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 {
|
|
10
|
-
|
|
9
|
+
import {
|
|
10
|
+
analyzeInput,
|
|
11
|
+
saveImageSrc,
|
|
12
|
+
saveItemStorage,
|
|
13
|
+
saveRelation,
|
|
14
|
+
} from '@/browser/property/actors/saveValueToDb' // import { updateMachineContext } from '@/browser/helpers'
|
|
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
|
},
|
|
22
|
+
// actions: {
|
|
23
|
+
// updateContext: updateMachineContext,
|
|
24
|
+
// },
|
|
16
25
|
actors: {
|
|
17
26
|
waitForDb,
|
|
18
27
|
hydrateFromDb,
|
|
19
28
|
initialize,
|
|
20
29
|
resolveRelatedValue,
|
|
21
30
|
resolveRemoteStorage,
|
|
22
|
-
|
|
31
|
+
analyzeInput,
|
|
32
|
+
saveImageSrc,
|
|
33
|
+
saveRelation,
|
|
34
|
+
saveItemStorage,
|
|
23
35
|
},
|
|
24
36
|
}).createMachine({
|
|
25
37
|
id: 'itemProperty',
|
|
@@ -48,7 +60,20 @@ export const propertyMachine = setup({
|
|
|
48
60
|
}),
|
|
49
61
|
target: '.saving',
|
|
50
62
|
},
|
|
51
|
-
updateContext:
|
|
63
|
+
updateContext: {
|
|
64
|
+
actions: assign(({ context, event }) => {
|
|
65
|
+
const newContext = Object.assign({}, context)
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < Object.keys(event).length; i++) {
|
|
68
|
+
const key = Object.keys(event)[i]
|
|
69
|
+
if (key === 'type') {
|
|
70
|
+
continue
|
|
71
|
+
}
|
|
72
|
+
newContext[key] = event[key]
|
|
73
|
+
}
|
|
74
|
+
return newContext
|
|
75
|
+
}),
|
|
76
|
+
},
|
|
52
77
|
},
|
|
53
78
|
states: {
|
|
54
79
|
idle: {},
|
|
@@ -120,23 +145,60 @@ export const propertyMachine = setup({
|
|
|
120
145
|
},
|
|
121
146
|
},
|
|
122
147
|
saving: {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
+
},
|
|
129
163
|
},
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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',
|
|
135
193
|
},
|
|
136
194
|
},
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
195
|
+
onDone: {
|
|
196
|
+
target: 'idle',
|
|
197
|
+
actions: assign(({ context }) => {
|
|
198
|
+
return {
|
|
199
|
+
isSaving: false,
|
|
200
|
+
}
|
|
201
|
+
}),
|
|
140
202
|
},
|
|
141
203
|
},
|
|
142
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,200 @@
|
|
|
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
|
+
}
|
|
110
|
+
|
|
111
|
+
if (newValueType === 'url') {
|
|
112
|
+
fileData = await fetchImage(newValue as string)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (newValue instanceof File) {
|
|
116
|
+
fileName = newValue.name
|
|
117
|
+
mimeType = newValue.type
|
|
118
|
+
fileData = await readFileAsArrayBuffer(newValue)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!fileData) {
|
|
122
|
+
throw new Error('No file data found')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const newImageSeedLocalId = await createSeed({
|
|
126
|
+
type: 'image',
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
if (!fileName) {
|
|
130
|
+
fileName = newImageSeedLocalId
|
|
131
|
+
if (mimeType) {
|
|
132
|
+
fileName += `.${mimeType.split('/')[1]}`
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const filePath = `/files/images/${fileName}`
|
|
137
|
+
|
|
138
|
+
const imageVersionLocalId = await createVersion({
|
|
139
|
+
seedLocalId: newImageSeedLocalId,
|
|
140
|
+
seedType: 'image',
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
if (fileData instanceof ArrayBuffer) {
|
|
144
|
+
await fs.promises.writeFile(filePath, new Uint8Array(fileData))
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (typeof fileData === 'string') {
|
|
148
|
+
await fs.promises.writeFile(filePath, fileData)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const refResolvedDisplayValue = await getContentUrlFromPath(filePath)
|
|
152
|
+
|
|
153
|
+
if (!localId) {
|
|
154
|
+
await createMetadata(
|
|
155
|
+
{
|
|
156
|
+
propertyName,
|
|
157
|
+
propertyValue: newImageSeedLocalId,
|
|
158
|
+
seedLocalId,
|
|
159
|
+
seedUid,
|
|
160
|
+
versionLocalId,
|
|
161
|
+
versionUid,
|
|
162
|
+
modelName: itemModelName,
|
|
163
|
+
schemaUid,
|
|
164
|
+
refSeedType: 'image',
|
|
165
|
+
refResolvedDisplayValue,
|
|
166
|
+
refResolvedValue: fileName,
|
|
167
|
+
},
|
|
168
|
+
propertyRecordSchema,
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (localId) {
|
|
173
|
+
await updateItemPropertyValue({
|
|
174
|
+
propertyLocalId: localId,
|
|
175
|
+
propertyName: propertyNameRaw,
|
|
176
|
+
newValue: newImageSeedLocalId,
|
|
177
|
+
seedLocalId,
|
|
178
|
+
versionLocalId,
|
|
179
|
+
modelName: itemModelName,
|
|
180
|
+
schemaUid,
|
|
181
|
+
refSeedType: 'image',
|
|
182
|
+
refResolvedDisplayValue,
|
|
183
|
+
refResolvedValue: fileName,
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
sendBack({
|
|
188
|
+
type: 'updateContext',
|
|
189
|
+
propertyValue: newImageSeedLocalId,
|
|
190
|
+
refSeedType: 'image',
|
|
191
|
+
renderValue: refResolvedDisplayValue,
|
|
192
|
+
resolvedDisplayValue: refResolvedDisplayValue,
|
|
193
|
+
resolvedValue: fileName,
|
|
194
|
+
})
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
_saveImageSrc().then(() => {
|
|
198
|
+
sendBack({ type: 'saveImageSrcSuccess' })
|
|
199
|
+
})
|
|
200
|
+
})
|
|
@@ -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
|
+
})
|
|
@@ -358,7 +358,7 @@ const createMetadataRecordsForStorageTransactionId = async (
|
|
|
358
358
|
versionLocalId,
|
|
359
359
|
versionUid,
|
|
360
360
|
refValueType: 'file',
|
|
361
|
-
refResolvedValue: `${propertyValue}
|
|
361
|
+
refResolvedValue: `${propertyValue}${propertyDef.filenameSuffix}`,
|
|
362
362
|
modelType: seedUidToModelType.get(seedUid),
|
|
363
363
|
createdAt: Date.now(),
|
|
364
364
|
updatedAt: Date.now(),
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { versions } from '@/shared/seedSchema'
|
|
2
|
+
import { count, max } from 'drizzle-orm'
|
|
3
|
+
import { getAppDb } from '@/browser/db/sqlWasmClient'
|
|
4
|
+
|
|
5
|
+
export const getVersionData = () => {
|
|
6
|
+
const appDb = getAppDb()
|
|
7
|
+
|
|
8
|
+
return appDb.$with('versionData').as(
|
|
9
|
+
appDb
|
|
10
|
+
.select({
|
|
11
|
+
seedLocalId: versions.seedLocalId,
|
|
12
|
+
seedUid: versions.seedUid,
|
|
13
|
+
latestVersionUid: versions.uid,
|
|
14
|
+
latestVersionLocalId: versions.localId,
|
|
15
|
+
versionsCount: count(versions.localId).as('versionsCount'),
|
|
16
|
+
lastVersionPublishedAt: max(versions.attestationCreatedAt).as(
|
|
17
|
+
'lastVersionPublishedAt',
|
|
18
|
+
),
|
|
19
|
+
lastLocalUpdateAt: max(versions.createdAt).as('lastLocalUpdateAt'),
|
|
20
|
+
})
|
|
21
|
+
.from(versions)
|
|
22
|
+
.groupBy(versions.seedLocalId),
|
|
23
|
+
)
|
|
24
|
+
}
|