@seedprotocol/sdk 0.2.43 → 0.2.44

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 (140) hide show
  1. package/dist/{ArweaveClient-BXD_aTsx.js → ArweaveClient-CA1Vsnow.js} +2 -2
  2. package/dist/{ArweaveClient-BXD_aTsx.js.map → ArweaveClient-CA1Vsnow.js.map} +1 -1
  3. package/dist/{ArweaveClient-CkcZD_QE.js → ArweaveClient-MgJXScYG.js} +2 -2
  4. package/dist/{ArweaveClient-CkcZD_QE.js.map → ArweaveClient-MgJXScYG.js.map} +1 -1
  5. package/dist/{Db-Bug4efsE.js → Db-BEoczaGe.js} +156 -165
  6. package/dist/{Db-Bug4efsE.js.map → Db-BEoczaGe.js.map} +1 -1
  7. package/dist/{Db-B4XyOmGy.js → Db-Y1GWsyNL.js} +34 -43
  8. package/dist/{Db-B4XyOmGy.js.map → Db-Y1GWsyNL.js.map} +1 -1
  9. package/dist/{EasClient-BNwSwDTO.js → EasClient-BjlbuffX.js} +2 -2
  10. package/dist/{EasClient-BNwSwDTO.js.map → EasClient-BjlbuffX.js.map} +1 -1
  11. package/dist/{EasClient-epqE9aWI.js → EasClient-Cg1q8lBu.js} +2 -2
  12. package/dist/{EasClient-epqE9aWI.js.map → EasClient-Cg1q8lBu.js.map} +1 -1
  13. package/dist/FileManager-D53H3aUS.js +781 -0
  14. package/dist/FileManager-D53H3aUS.js.map +1 -0
  15. package/dist/FileManager-t4zcT3NL.js +38 -0
  16. package/dist/FileManager-t4zcT3NL.js.map +1 -0
  17. package/dist/{Item-vjJTzf1d.js → Item-BleJyiA2.js} +9 -12
  18. package/dist/{Item-vjJTzf1d.js.map → Item-BleJyiA2.js.map} +1 -1
  19. package/dist/{ItemProperty-DJpbernm.js → ItemProperty-CH7JmVg-.js} +9 -12
  20. package/dist/{ItemProperty-DJpbernm.js.map → ItemProperty-CH7JmVg-.js.map} +1 -1
  21. package/dist/{QueryClient-Do0C7Jnt.js → QueryClient-BKjgZnSt.js} +2 -2
  22. package/dist/{QueryClient-Do0C7Jnt.js.map → QueryClient-BKjgZnSt.js.map} +1 -1
  23. package/dist/{QueryClient-Ckl99FYC.js → QueryClient-CDsEencG.js} +2 -2
  24. package/dist/{QueryClient-Ckl99FYC.js.map → QueryClient-CDsEencG.js.map} +1 -1
  25. package/dist/bin.js +28 -27
  26. package/dist/bin.js.map +1 -1
  27. package/dist/{constants-BakHTrB9.js → constants-BIdH8wc3.js} +66 -41
  28. package/dist/constants-BIdH8wc3.js.map +1 -0
  29. package/dist/{index-DcPIAiHD.js → index-DanGFTTF.js} +1263 -1536
  30. package/dist/index-DanGFTTF.js.map +1 -0
  31. package/dist/{index-BWIn7kWN.js → index-Dk6K4W4n.js} +9 -12
  32. package/dist/index-Dk6K4W4n.js.map +1 -0
  33. package/dist/main.js +7 -10
  34. package/dist/main.js.map +1 -1
  35. package/dist/node/codegen/templates/index.njk +0 -4
  36. package/dist/{seed.schema.config-DGcg6TCS.js → seed.schema.config-DdCq87m_.js} +9 -11
  37. package/dist/seed.schema.config-DdCq87m_.js.map +1 -0
  38. package/dist/seedSchema/index.ts +0 -2
  39. package/dist/src/BaseFileManager.ts +22 -2
  40. package/dist/src/BaseItem.ts +4 -3
  41. package/dist/src/BaseItemProperty.ts +2 -2
  42. package/dist/src/FileDownloader.ts +63 -0
  43. package/dist/src/FileManager.ts +37 -6
  44. package/dist/src/ImageResizer.ts +84 -0
  45. package/dist/src/analyzeInput.ts +22 -2
  46. package/dist/src/constants.ts +67 -60
  47. package/dist/src/createMetadata.ts +27 -2
  48. package/dist/src/download.ts +45 -202
  49. package/dist/src/filesDownload.ts +326 -0
  50. package/dist/src/getItem.ts +5 -0
  51. package/dist/src/getPublishPayload.ts +15 -8
  52. package/dist/src/helpers.ts +0 -14
  53. package/dist/src/imageResize.ts +507 -0
  54. package/dist/src/model.ts +6 -5
  55. package/dist/src/saveImageSrc.ts +15 -1
  56. package/dist/src/syncDbWithEas.ts +0 -90
  57. package/dist/src/updateItemPropertyValue.ts +16 -3
  58. package/dist/src/waitForDb.ts +18 -17
  59. package/dist/types/src/Item/BaseItem.d.ts +2 -2
  60. package/dist/types/src/Item/BaseItem.d.ts.map +1 -1
  61. package/dist/types/src/ItemProperty/BaseItemProperty.d.ts +2 -2
  62. package/dist/types/src/ItemProperty/BaseItemProperty.d.ts.map +1 -1
  63. package/dist/types/src/ItemProperty/service/actors/saveValueToDb/analyzeInput.d.ts.map +1 -1
  64. package/dist/types/src/ItemProperty/service/actors/saveValueToDb/saveImageSrc.d.ts.map +1 -1
  65. package/dist/types/src/browser/helpers/FileManager.d.ts +5 -1
  66. package/dist/types/src/browser/helpers/FileManager.d.ts.map +1 -1
  67. package/dist/types/src/browser/workers/FileDownloader.d.ts +8 -0
  68. package/dist/types/src/browser/workers/FileDownloader.d.ts.map +1 -0
  69. package/dist/types/src/browser/workers/ImageResizer.d.ts +9 -0
  70. package/dist/types/src/browser/workers/ImageResizer.d.ts.map +1 -0
  71. package/dist/types/src/browser/workers/content-hash.d.ts.map +1 -0
  72. package/dist/types/src/browser/workers/filesDownload.d.ts +3 -0
  73. package/dist/types/src/browser/workers/filesDownload.d.ts.map +1 -0
  74. package/dist/types/src/browser/workers/imageResize.d.ts +3 -0
  75. package/dist/types/src/browser/workers/imageResize.d.ts.map +1 -0
  76. package/dist/types/src/db/read/getItem.d.ts.map +1 -1
  77. package/dist/types/src/db/read/getPublishPayload.d.ts.map +1 -1
  78. package/dist/types/src/db/write/createMetadata.d.ts.map +1 -1
  79. package/dist/types/src/db/write/updateItemPropertyValue.d.ts +5 -1
  80. package/dist/types/src/db/write/updateItemPropertyValue.d.ts.map +1 -1
  81. package/dist/types/src/events/files/download.d.ts.map +1 -1
  82. package/dist/types/src/events/files/index.d.ts.map +1 -1
  83. package/dist/types/src/events/item/syncDbWithEas.d.ts.map +1 -1
  84. package/dist/types/src/helpers/FileManager/BaseFileManager.d.ts +4 -0
  85. package/dist/types/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
  86. package/dist/types/src/helpers/constants.d.ts +7 -0
  87. package/dist/types/src/helpers/constants.d.ts.map +1 -1
  88. package/dist/types/src/helpers/files.d.ts +1 -1
  89. package/dist/types/src/helpers/files.d.ts.map +1 -1
  90. package/dist/types/src/node/helpers/FileManager.d.ts +5 -0
  91. package/dist/types/src/node/helpers/FileManager.d.ts.map +1 -1
  92. package/dist/types/src/schema/model/index.d.ts +2 -2
  93. package/dist/types/src/schema/model/index.d.ts.map +1 -1
  94. package/dist/types/src/seedSchema/index.d.ts +0 -2
  95. package/dist/types/src/seedSchema/index.d.ts.map +1 -1
  96. package/dist/types/src/services/allItems/actors/initialize.d.ts.map +1 -1
  97. package/dist/types/src/services/internal/constants.d.ts +2 -2
  98. package/dist/types/src/services/internal/constants.d.ts.map +1 -1
  99. package/dist/types/src/services/internal/helpers.d.ts.map +1 -1
  100. package/dist/types/src/types/fileManager.d.ts +15 -0
  101. package/dist/types/src/types/fileManager.d.ts.map +1 -0
  102. package/dist/types/src/types/model.d.ts +6 -5
  103. package/dist/types/src/types/model.d.ts.map +1 -1
  104. package/package.json +5 -3
  105. package/dist/FileManager-CXk83EW5.js +0 -16
  106. package/dist/FileManager-CXk83EW5.js.map +0 -1
  107. package/dist/FileManager-DXi-X7r5.js +0 -28
  108. package/dist/FileManager-DXi-X7r5.js.map +0 -1
  109. package/dist/constants-BakHTrB9.js.map +0 -1
  110. package/dist/content-hash.js +0 -27
  111. package/dist/content-hash.js.map +0 -1
  112. package/dist/index-BWIn7kWN.js.map +0 -1
  113. package/dist/index-DcPIAiHD.js.map +0 -1
  114. package/dist/seed.schema.config-DGcg6TCS.js.map +0 -1
  115. package/dist/types/__tests__/__mocks__/browser/project/schema.d.ts +0 -52
  116. package/dist/types/__tests__/__mocks__/browser/project/schema.d.ts.map +0 -1
  117. package/dist/types/__tests__/__mocks__/node/schema.d.ts +0 -52
  118. package/dist/types/__tests__/__mocks__/node/schema.d.ts.map +0 -1
  119. package/dist/types/__tests__/browser/db/drizzle.test.d.ts +0 -2
  120. package/dist/types/__tests__/browser/db/drizzle.test.d.ts.map +0 -1
  121. package/dist/types/__tests__/browser/property/propertyMachine.test.d.ts +0 -2
  122. package/dist/types/__tests__/browser/property/propertyMachine.test.d.ts.map +0 -1
  123. package/dist/types/__tests__/browser/react/index.test.d.ts +0 -2
  124. package/dist/types/__tests__/browser/react/index.test.d.ts.map +0 -1
  125. package/dist/types/__tests__/dist/exports.test.d.ts +0 -2
  126. package/dist/types/__tests__/dist/exports.test.d.ts.map +0 -1
  127. package/dist/types/__tests__/fs/index.test.d.ts +0 -2
  128. package/dist/types/__tests__/fs/index.test.d.ts.map +0 -1
  129. package/dist/types/__tests__/index.test.d.ts +0 -2
  130. package/dist/types/__tests__/index.test.d.ts.map +0 -1
  131. package/dist/types/__tests__/node/Item/Item.test.d.ts +0 -2
  132. package/dist/types/__tests__/node/Item/Item.test.d.ts.map +0 -1
  133. package/dist/types/__tests__/node/setup.d.ts +0 -2
  134. package/dist/types/__tests__/node/setup.d.ts.map +0 -1
  135. package/dist/types/__tests__/scripts/bin.test.d.ts +0 -2
  136. package/dist/types/__tests__/scripts/bin.test.d.ts.map +0 -1
  137. package/dist/types/__tests__/setup.d.ts +0 -2
  138. package/dist/types/__tests__/setup.d.ts.map +0 -1
  139. package/dist/types/src/workers/content-hash.d.ts.map +0 -1
  140. /package/dist/types/src/{workers → browser/workers}/content-hash.d.ts +0 -0
@@ -145,7 +145,12 @@ const processRelationProperty = async (
145
145
  seedSchemaUid,
146
146
  versionUid,
147
147
  listOfAttestations: [],
148
- propertiesToUpdate: [],
148
+ propertiesToUpdate: [
149
+ {
150
+ publishLocalId: relationProperty.localId,
151
+ propertySchemaUid: relationProperty.schemaUid,
152
+ },
153
+ ],
149
154
  }
150
155
 
151
156
  const { itemBasicProperties, itemUploadProperties } =
@@ -315,20 +320,22 @@ export const getPublishPayload = async (
315
320
  }
316
321
  }
317
322
 
318
- itemPublishData = await processBasicProperties(
319
- itemBasicProperties,
320
- itemPublishData,
321
- )
322
-
323
- multiPublishPayload.push(itemPublishData)
324
-
325
323
  for (const relationProperty of itemRelationProperties) {
326
324
  multiPublishPayload = await processRelationProperty(
327
325
  relationProperty,
328
326
  multiPublishPayload,
329
327
  uploadedTransactions,
330
328
  )
329
+ itemBasicProperties.push(relationProperty)
331
330
  }
331
+
332
+ itemPublishData = await processBasicProperties(
333
+ itemBasicProperties,
334
+ itemPublishData,
335
+ )
336
+
337
+ multiPublishPayload.push(itemPublishData)
338
+
332
339
 
333
340
  for (const listProperty of itemListProperties) {
334
341
  multiPublishPayload = await processListProperty(
@@ -80,22 +80,8 @@ export const downloadFile = async (url: string, localFilePath: string) => {
80
80
  }
81
81
  }
82
82
 
83
- // if (filename === '_journal.json') {
84
- // const exists = await fs.promises.exists(localFilePath)
85
- // if (exists) {
86
- // await fs.promises.rm(localFilePath)
87
- // }
88
- // await fs.promises.writeFile(localFilePath, fileData)
89
- // }
90
- //
91
- // if (filename !== '_journal.json') {
92
- // await fs.promises.writeFile(localFilePath, fileData)
93
- // }
94
83
  await fs.promises.writeFile(localFilePath, fileData)
95
84
  } catch (error) {
96
- if (JSON.stringify(error).includes('File exists')) {
97
- const fileData = await fs.promises.readFile(localFilePath, 'utf-8')
98
- }
99
85
  logger(`[Error] Failed to download file from ${url}:`, error)
100
86
  }
101
87
 
@@ -0,0 +1,507 @@
1
+ import path from "path";
2
+
3
+ type BrowserImageResizerConfigBase = {
4
+ /**
5
+ * Algorithm used for downscaling
6
+ *
7
+ * * `null`: Just resize with `drawImage()`. The best quality and fastest.
8
+ * * `bilinear`: Better quality, slower. Comes from upstream (ericnogralesbrowser-image-resizer).
9
+ * * `hermite`: Worse quality, faster. Comes from [viliusle/Hermite-resize](https://github.com/viliusle/Hermite-resize). Will dispatch workers for better performance.
10
+ * * `hermite_single`: Worse quality, faster. Single-threaded.
11
+ *
12
+ * default: null
13
+ */
14
+ algorithm: 'bilinear' | 'hermite' | 'hermite_single' | 'null' | null;
15
+
16
+ /**
17
+ * Whether to process downscaling by `drawImage(source, 0, 0, source.width / 2, source.height / 2)`
18
+ * until the size is smaller than twice the target size.
19
+ *
20
+ * There seems to be no situation where it is necessary to change to false.
21
+ *
22
+ * default: true
23
+ */
24
+ processByHalf: boolean;
25
+
26
+ maxWidth: number;
27
+ maxHeight: number;
28
+ maxSize?: number; // ???
29
+
30
+ /**
31
+ * Scale ratio. Strictly limited to maxWidth.
32
+ */
33
+ scaleRatio?: number;
34
+
35
+ /**
36
+ * Output logs to console
37
+ */
38
+ debug: boolean;
39
+ }
40
+
41
+
42
+ type BrowserImageResizerConfigWithConvertedOutput = BrowserImageResizerConfigBase & {
43
+ quality: number;
44
+ mimeType: string;
45
+ };
46
+
47
+ type BrowserImageResizerConfigWithOffscreenCanvasOutput = BrowserImageResizerConfigBase & {
48
+ mimeType: null;
49
+ }
50
+
51
+ type BrowserImageResizerConfig = BrowserImageResizerConfigWithConvertedOutput | BrowserImageResizerConfigWithOffscreenCanvasOutput;
52
+
53
+ type WorkerSouceData = {
54
+ source: ImageData;
55
+ startY: number;
56
+ height: number;
57
+ }
58
+
59
+ export default `(
60
+ ${
61
+ function () {
62
+
63
+ async function listFilesInDirectory(directoryHandle: FileSystemDirectoryHandle) {
64
+ const entries: { name: string; kind: FileSystemHandleKind }[] = [];
65
+
66
+ for await (const [name, handle] of directoryHandle.entries()) {
67
+ entries.push({
68
+ name,
69
+ kind: handle.kind,
70
+ })
71
+ }
72
+
73
+ return entries;
74
+ }
75
+
76
+ const getFileHandle = async (path: string, rootHandle: FileSystemDirectoryHandle | null = null): Promise<FileSystemFileHandle> => {
77
+ // Split the path into segments
78
+ const segments = path.split('/').filter(Boolean);
79
+
80
+ // Start from the root directory if not provided
81
+ if (!rootHandle) {
82
+ rootHandle = await navigator.storage.getDirectory();
83
+ }
84
+
85
+ let currentHandle = rootHandle;
86
+
87
+ // Traverse the path segments
88
+ for (let i = 0; i < segments.length; i++) {
89
+ const segment = segments[i];
90
+ const isLastSegment = i === segments.length - 1;
91
+
92
+ try {
93
+
94
+ for await (const [name, handle] of currentHandle.entries()) {
95
+ if (name !== segment) {
96
+ continue
97
+ }
98
+
99
+ if (isLastSegment) {
100
+ if (handle.kind === 'file') {
101
+ return handle as FileSystemFileHandle; // Return the file handle if found
102
+ } else {
103
+ throw new Error(`Path '${path}' refers to a directory, not a file.`);
104
+ }
105
+ } else if (handle.kind === 'directory') {
106
+ currentHandle = handle as FileSystemDirectoryHandle; // Traverse into the directory
107
+ } else {
108
+ throw new Error(`Invalid path segment '${segment}'`);
109
+ }
110
+ }
111
+ } catch (err) {
112
+ if (err instanceof Error && err.name === 'NotFoundError') {
113
+ throw new Error(`Path '${path}' does not exist.`);
114
+ } else {
115
+ throw err;
116
+ }
117
+ }
118
+ }
119
+
120
+ throw new Error(`Path '${path}' could not be resolved.`);
121
+ }
122
+
123
+ async function getFileFromOPFS(path: string): Promise<File> {
124
+
125
+ const fileHandleAsync = await getFileHandle(path);
126
+ const file = await fileHandleAsync.getFile();
127
+ return file;
128
+
129
+ }
130
+
131
+ const DEFAULT_CONFIG = {
132
+ argorithm: 'null',
133
+ processByHalf: true,
134
+ quality: 0.5,
135
+ maxWidth: 800,
136
+ maxHeight: 600,
137
+ debug: false,
138
+ mimeType: 'image/jpeg',
139
+ } as const;
140
+
141
+ function isIos() {
142
+ if (typeof navigator === 'undefined') return false;
143
+ if (!navigator.userAgent) return false;
144
+ return /iPad|iPhone|iPod/.test(navigator.userAgent);
145
+ }
146
+
147
+ const getTargetHeight = (srcHeight: number, scale: number, config: BrowserImageResizerConfig) => {
148
+ return Math.min(Math.floor(srcHeight * scale), config.maxHeight);
149
+ }
150
+
151
+ const findMaxWidth = (config: BrowserImageResizerConfig, canvas: { width: number; height: number }) => {
152
+ //Let's find the max available width for scaled image
153
+ const ratio = canvas.width / canvas.height;
154
+ let mWidth = Math.min(
155
+ canvas.width,
156
+ config.maxWidth,
157
+ ratio * config.maxHeight
158
+ );
159
+ if (
160
+ config.maxSize &&
161
+ config.maxSize > 0 &&
162
+ config.maxSize < (canvas.width * canvas.height) / 1000
163
+ )
164
+ mWidth = Math.min(
165
+ mWidth,
166
+ Math.floor((config.maxSize * 1000) / canvas.height)
167
+ );
168
+ if (!!config.scaleRatio)
169
+ mWidth = Math.min(mWidth, Math.floor(config.scaleRatio * canvas.width));
170
+
171
+ const rHeight = getTargetHeight(canvas.height, mWidth / canvas.width, config);
172
+
173
+ // console.log(
174
+ // 'browser-image-resizer: original image size = ' +
175
+ // canvas.width +
176
+ // ' px (width) X ' +
177
+ // canvas.height +
178
+ // ' px (height)'
179
+ // );
180
+ // console.log(
181
+ // 'browser-image-resizer: scaled image size = ' +
182
+ // mWidth +
183
+ // ' px (width) X ' +
184
+ // rHeight +
185
+ // ' px (height)'
186
+ // );
187
+ if (mWidth <= 0) {
188
+ mWidth = 1;
189
+ console.warn("browser-image-resizer: image size is too small");
190
+ }
191
+
192
+ if (isIos() && mWidth * rHeight > 167777216) {
193
+ console.error("browser-image-resizer: image size is too large for iOS WebKit.", mWidth, rHeight);
194
+ throw new Error("browser-image-resizer: image size is too large for iOS WebKit.");
195
+ }
196
+
197
+ return mWidth;
198
+ }
199
+
200
+ /**
201
+ * Hermite resize, multicore version - fast image resize/resample using Hermite filter.
202
+ */
203
+ const resample = (srcCanvas: OffscreenCanvas, destCanvas: OffscreenCanvas, config: { debug?: boolean }) => {
204
+ return new Promise<void>((resolve, reject) => {
205
+
206
+ const ratio_h = srcCanvas.height / destCanvas.height;
207
+ const cores = Math.min(navigator.hardwareConcurrency || 4, 4)
208
+
209
+ //prepare source and target data for workers
210
+ const ctx = srcCanvas.getContext('2d');
211
+ if (!ctx) return reject('Canvas is empty (resample)');
212
+
213
+ const data_part: WorkerSouceData[] = [];
214
+ const block_height = Math.ceil(srcCanvas.height / cores / 2) * 2;
215
+ let end_y = -1;
216
+ for (let c = 0; c < cores; c++) {
217
+ //source
218
+ const offset_y = end_y + 1;
219
+ if (offset_y >= srcCanvas.height) {
220
+ //size too small, nothing left for this core
221
+ continue;
222
+ }
223
+
224
+ end_y = Math.min(offset_y + block_height - 1, srcCanvas.height - 1);
225
+
226
+ const current_block_height = Math.min(block_height, srcCanvas.height - offset_y);
227
+
228
+ console.log('browser-image-resizer: source split: ', '#' + c, offset_y, end_y, 'height: ' + current_block_height);
229
+
230
+ data_part.push({
231
+ source: ctx.getImageData(0, offset_y, srcCanvas.width, block_height),
232
+ startY: Math.ceil(offset_y / ratio_h),
233
+ height: current_block_height
234
+ });
235
+ }
236
+
237
+ //start
238
+ const destCtx = destCanvas.getContext('2d');
239
+ if (!destCtx) return reject('Canvas is empty (resample dest)');
240
+ let workers_in_use = data_part.length;
241
+ for (let c = 0; c < data_part.length; c++) {
242
+
243
+ //draw
244
+ const height_part = Math.ceil(data_part[c].height / ratio_h);
245
+ const target = destCtx.createImageData(destCanvas.width, height_part);
246
+ // target.data.set(event.data.target);
247
+ destCtx.putImageData(target, 0, data_part[c].startY);
248
+
249
+ }
250
+ });
251
+ };
252
+
253
+ /**
254
+ * Hermite resize - fast image resize/resample using Hermite filter. 1 cpu version!
255
+ */
256
+ const resampleSingle = (srcCanvasData: ImageData, destCanvasData: ImageData,) => {
257
+ const ratio_w = srcCanvasData.width / destCanvasData.width;
258
+ const ratio_h = srcCanvasData.height / destCanvasData.height;
259
+ const ratio_w_half = Math.ceil(ratio_w / 2);
260
+ const ratio_h_half = Math.ceil(ratio_h / 2);
261
+
262
+ const data = srcCanvasData.data;
263
+ const data2 = destCanvasData.data;
264
+
265
+ for (let j = 0; j < destCanvasData.height; j++) {
266
+ for (let i = 0; i < destCanvasData.width; i++) {
267
+ const x2 = (i + j * destCanvasData.width) * 4;
268
+ let weight = 0;
269
+ let weights = 0;
270
+ let weights_alpha = 0;
271
+ let gx_r = 0;
272
+ let gx_g = 0;
273
+ let gx_b = 0;
274
+ let gx_a = 0;
275
+ const center_y = j * ratio_h;
276
+
277
+ const xx_start = Math.floor(i * ratio_w);
278
+ const xx_stop = Math.min(Math.ceil((i + 1) * ratio_w), srcCanvasData.width);
279
+ const yy_start = Math.floor(j * ratio_h);
280
+ const yy_stop = Math.min(Math.ceil((j + 1) * ratio_h), srcCanvasData.height);
281
+
282
+ for (let yy = yy_start; yy < yy_stop; yy++) {
283
+ let dy = Math.abs(center_y - yy) / ratio_h_half;
284
+ let center_x = i * ratio_w;
285
+ let w0 = dy * dy; //pre-calc part of w
286
+ for (let xx = xx_start; xx < xx_stop; xx++) {
287
+ let dx = Math.abs(center_x - xx) / ratio_w_half;
288
+ let w = Math.sqrt(w0 + dx * dx);
289
+ if (w >= 1) {
290
+ //pixel too far
291
+ continue;
292
+ }
293
+ //hermite filter
294
+ weight = 2 * w * w * w - 3 * w * w + 1;
295
+ let pos_x = 4 * (xx + yy * srcCanvasData.width);
296
+ //alpha
297
+ gx_a += weight * data[pos_x + 3];
298
+ weights_alpha += weight;
299
+ //colors
300
+ if (data[pos_x + 3] < 255)
301
+ weight = weight * data[pos_x + 3] / 250;
302
+ gx_r += weight * data[pos_x];
303
+ gx_g += weight * data[pos_x + 1];
304
+ gx_b += weight * data[pos_x + 2];
305
+ weights += weight;
306
+ }
307
+ }
308
+ data2[x2] = gx_r / weights;
309
+ data2[x2 + 1] = gx_g / weights;
310
+ data2[x2 + 2] = gx_b / weights;
311
+ data2[x2 + 3] = gx_a / weights_alpha;
312
+ }
313
+ }
314
+ };
315
+
316
+ /**
317
+ * Hermite resize. Detect cpu count and use best option for user.
318
+ */
319
+ const resampleAuto = (srcCanvas: OffscreenCanvas, destCanvas: OffscreenCanvas, config: { debug?: boolean, argorithm?: string }) => {
320
+ if (!!globalThis.Worker && navigator.hardwareConcurrency > 1 && config?.argorithm !== 'hermite_single') {
321
+ //workers supported and we have at least 2 cpu cores - using multithreading
322
+ return resample(srcCanvas, destCanvas, config);
323
+ } else {
324
+ //1 cpu version
325
+ const { srcImgData, destImgData } = getImageData(srcCanvas, destCanvas);
326
+ resampleSingle(srcImgData, destImgData, config);
327
+ destCanvas.getContext('2d')!.putImageData(destImgData, 0, 0);
328
+ return;
329
+ }
330
+ };
331
+
332
+
333
+ async function scaleCanvasWithAlgorithm(canvas: OffscreenCanvas, config: BrowserImageResizerConfig & { outputWidth: number }) {
334
+ const scale = config.outputWidth / canvas.width;
335
+
336
+ const scaled = new OffscreenCanvas(Math.floor(config.outputWidth), getTargetHeight(canvas.height, scale, config));
337
+
338
+ switch (config.algorithm) {
339
+ case 'hermite': {
340
+ await resampleAuto(canvas, scaled, config as BrowserImageResizerConfig & { algorithm: 'hermite' | 'hermite_single' });
341
+ break;
342
+ } case 'hermite_single': {
343
+ const { srcImgData, destImgData } = getImageData(canvas, scaled);
344
+ resampleSingle(srcImgData, destImgData,);
345
+ scaled?.getContext('2d')?.putImageData(destImgData, 0, 0);
346
+ break;
347
+ } case 'bilinear': {
348
+ // const { srcImgData, destImgData } = getImageData(canvas, scaled);
349
+ // bilinear(srcImgData, destImgData, scale);
350
+ // scaled?.getContext('2d')?.putImageData(destImgData, 0, 0);
351
+ break;
352
+ } default: {
353
+ scaled.getContext('2d')?.drawImage(canvas, 0, 0, scaled.width, scaled.height);
354
+ break;
355
+ }
356
+ }
357
+
358
+ return scaled;
359
+ }
360
+
361
+ const getHalfScaleCanvas = (src: OffscreenCanvas | HTMLCanvasElement) => {
362
+ const half = new OffscreenCanvas(src.width / 2, src.height / 2);
363
+
364
+ half
365
+ ?.getContext('2d')
366
+ ?.drawImage(src, 0, 0, half.width, half.height);
367
+
368
+ return half;
369
+ }
370
+
371
+ const getImageData = (canvas: OffscreenCanvas, scaled: OffscreenCanvas) => {
372
+ const srcImgData = canvas
373
+ ?.getContext('2d')
374
+ ?.getImageData(0, 0, canvas.width, canvas.height);
375
+ const destImgData = scaled
376
+ ?.getContext('2d')
377
+ ?.createImageData(scaled.width, scaled.height);
378
+
379
+ if (!srcImgData || !destImgData) throw Error('Canvas is empty (scaleCanvasWithAlgorithm). You should run this script after the document is ready.');
380
+
381
+ return { srcImgData, destImgData };
382
+ }
383
+
384
+ async function saveBlobToOPFS(filePath: string, blob: Blob): Promise<void> {
385
+ // Access the OPFS root directory
386
+ const rootHandle = await navigator.storage.getDirectory();
387
+
388
+ // Split the filePath into directory segments and file name
389
+ const segments = filePath.split('/').filter(Boolean);
390
+ const fileName = segments.pop(); // Extract the file name
391
+ if (!fileName) {
392
+ throw new Error('Invalid file path: No file name provided.');
393
+ }
394
+
395
+ // Traverse or create directories as needed
396
+ let currentDirHandle = rootHandle;
397
+ for (const segment of segments) {
398
+ currentDirHandle = await currentDirHandle.getDirectoryHandle(segment, { create: true });
399
+ }
400
+
401
+ // Create or open the file in OPFS
402
+ const fileHandle = await currentDirHandle.getFileHandle(fileName, { create: true });
403
+
404
+ // Write the Blob to the file
405
+ const writableStream = await fileHandle.createWritable();
406
+ await writableStream.write(blob);
407
+ await writableStream.close();
408
+ }
409
+
410
+
411
+ const imageResize = async (filePath: string, width: number, height: number) => {
412
+
413
+ console.log({filePath, width, height})
414
+
415
+ const config = {
416
+ ...DEFAULT_CONFIG,
417
+ algorithm: 'hermite_single',
418
+ mimeType: 'image/webp',
419
+ maxWidth: width,
420
+ maxHeight: height,
421
+ }
422
+
423
+ const rootHandle = await navigator.storage.getDirectory();
424
+
425
+ // List files in the root directory
426
+ const files = await listFilesInDirectory(rootHandle);
427
+ console.log({
428
+ message: 'listFilesInDirectory',
429
+ files
430
+ });
431
+
432
+ const file = await getFileFromOPFS(filePath);
433
+
434
+ const imageBitmap = await createImageBitmap(file);
435
+
436
+ let converting: OffscreenCanvas
437
+
438
+ if (isIos() && imageBitmap.width * imageBitmap.height > 16777216) {
439
+ const scale = Math.sqrt(16777216 / (imageBitmap.width * imageBitmap.height));
440
+ console.log(`browser-image-resizer: scale: Image is too large in iOS WebKit`);
441
+ converting = new OffscreenCanvas(Math.floor(imageBitmap.width * scale), Math.floor(imageBitmap.height * scale));
442
+ converting.getContext('2d')?.drawImage(imageBitmap, 0, 0, converting.width, converting.height);
443
+ } else {
444
+ converting = new OffscreenCanvas(imageBitmap.width, imageBitmap.height);
445
+ converting.getContext('2d')?.drawImage(imageBitmap, 0, 0);
446
+ }
447
+
448
+ if (!converting?.getContext('2d')) {
449
+ console.log('browser-image-resizer: Canvas Context is empty.')
450
+ }
451
+
452
+ const maxWidth = findMaxWidth(config, converting);
453
+
454
+ if (!maxWidth){
455
+ throw Error(`browser-image-resizer: maxWidth is ${maxWidth}!!`)
456
+ };
457
+
458
+ while (config.processByHalf && converting.width >= 2 * maxWidth) {
459
+ if (config.debug) console.log(`browser-image-resizer: scale: Scaling canvas by half from ${converting.width}`);
460
+ converting = getHalfScaleCanvas(converting);
461
+ }
462
+
463
+ if (converting.width > maxWidth) {
464
+ if (config.debug) console.log(`browser-image-resizer: scale: Scaling canvas by ${config.argorithm} from ${converting.width} to ${maxWidth}`);
465
+ converting = await scaleCanvasWithAlgorithm(
466
+ converting,
467
+ Object.assign(config, { outputWidth: maxWidth }),
468
+ );
469
+ }
470
+
471
+ if (config.mimeType === null) {
472
+ return converting;
473
+ }
474
+ const resizedBlob = await converting.convertToBlob({ type: config.mimeType, quality: config.quality });
475
+
476
+ const pathSegments = filePath.split('/');
477
+ const fileName = pathSegments.pop();
478
+ if (!fileName) {
479
+ throw Error('Invalid file path: No file name provided.');
480
+ }
481
+ const newSegments = [
482
+ ...pathSegments,
483
+ width,
484
+ ]
485
+ const fileNameParts = fileName.split('.')
486
+ const newFileName = `${fileNameParts[0]}.webp`
487
+ const newDirPath = newSegments.join('/');
488
+ const newFilePath = `${newDirPath}/${newFileName}`;
489
+
490
+ // Save resized image to OPFS with new name
491
+ await saveBlobToOPFS(newFilePath, resizedBlob)
492
+ globalThis.postMessage({
493
+ done: true,
494
+ filePath: newFilePath,
495
+ })
496
+
497
+ }
498
+
499
+ onmessage = async (e) => {
500
+ console.log('[imageResize] onmessage', e.data)
501
+ const { filePath, width, height } = e.data
502
+ await imageResize(filePath, width, height)
503
+ console.log(`[imageResize] Done`, filePath)
504
+ }
505
+ }.toString()
506
+ }
507
+ )()`
package/dist/src/model.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { PropertyStates, PropertyValue } from './property'
2
- import { Actor } from 'xstate'
2
+ import { Actor, AnyActorLogic } from 'xstate'
3
3
  import { Static } from '@sinclair/typebox'
4
- import { IModelClass, Item, TModelSchema } from '@/schema'
4
+ import { IModelClass, TModelSchema } from '@/schema'
5
+ import { BaseItem } from '@/Item/BaseItem'
5
6
 
6
7
  export type ModelDefinitions = {
7
8
  [modelName: string]: ModelClassType
@@ -19,16 +20,16 @@ export type ModelClassType = {
19
20
  originalConstructor: () => void
20
21
  schema: ModelSchema
21
22
  schemaUid?: string
22
- create: <T>(values: ModelValues<T>) => Promise<Item<T>>
23
+ create: (values: ModelValues<any>) => Promise<BaseItem<any>>
23
24
  }
24
25
 
25
- export type ModelValues<T> = Item<T> & {
26
+ export type ModelValues<T extends Record<string, any>> = BaseItem<any> & {
26
27
  schema: ModelSchema
27
28
  ModelClass?: ModelClassType
28
29
  [key: string & keyof T]: PropertyValue
29
30
  }
30
31
 
31
- export type StatesMap<T> = Map<string, Actor<T>>
32
+ export type StatesMap<T> = Map<string, Actor<T extends AnyActorLogic ? T : never>>
32
33
 
33
34
  // export type ModelSchema = {
34
35
  // [key: string]: TObject
@@ -15,6 +15,7 @@ import { getSchemaUidForSchemaDefinition } from '@/stores/eas'
15
15
  import { getSchemaUidForModel } from '@/db/read/getSchemaUidForModel'
16
16
  import { BaseFileManager } from '@/helpers/FileManager/BaseFileManager'
17
17
  import { eventEmitter } from '@/eventBus'
18
+ import { ImageSize } from '@/helpers/constants'
18
19
 
19
20
 
20
21
 
@@ -165,14 +166,23 @@ export const saveImageSrc = fromCallback<
165
166
  }
166
167
  }
167
168
 
169
+
170
+ await BaseFileManager.resizeImage({filePath, width: ImageSize.EXTRA_SMALL, height: ImageSize.EXTRA_SMALL})
171
+ await BaseFileManager.resizeImage({filePath, width: ImageSize.SMALL, height: ImageSize.SMALL})
172
+ await BaseFileManager.resizeImage({filePath, width: ImageSize.MEDIUM, height: ImageSize.MEDIUM})
173
+ await BaseFileManager.resizeImage({filePath, width: ImageSize.LARGE, height: ImageSize.LARGE})
174
+ await BaseFileManager.resizeImage({filePath, width: ImageSize.EXTRA_LARGE, height: ImageSize.EXTRA_LARGE})
175
+
168
176
  const refResolvedDisplayValue = await BaseFileManager.getContentUrlFromPath(filePath)
169
177
 
170
178
  if (!schemaUid) {
171
179
  schemaUid = getSchemaUidForSchemaDefinition(propertyName)
172
180
  }
173
181
 
182
+ let newLocalId
183
+
174
184
  if (!localId) {
175
- await createMetadata(
185
+ const result = await createMetadata(
176
186
  {
177
187
  propertyName,
178
188
  propertyValue: newImageSeedLocalId,
@@ -192,6 +202,8 @@ export const saveImageSrc = fromCallback<
192
202
  },
193
203
  propertyRecordSchema,
194
204
  )
205
+
206
+ newLocalId = result[0].localId
195
207
  }
196
208
 
197
209
  if (localId) {
@@ -215,6 +227,7 @@ export const saveImageSrc = fromCallback<
215
227
 
216
228
  sendBack({
217
229
  type: 'updateContext',
230
+ localId: newLocalId || localId,
218
231
  propertyValue: newImageSeedLocalId,
219
232
  refSeedType: 'image',
220
233
  refSchemaUid: imageSchemaUid,
@@ -223,6 +236,7 @@ export const saveImageSrc = fromCallback<
223
236
  refResolvedValue: fileName,
224
237
  localStorageDir: '/images',
225
238
  easDataType: 'bytes32',
239
+ schemaUid,
226
240
  })
227
241
  }
228
242