@dxos/plugin-wnfs 0.6.14-main.f49f251

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 (87) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +15 -0
  3. package/dist/lib/browser/FileCard-HJIZDWJF.mjs +39 -0
  4. package/dist/lib/browser/FileCard-HJIZDWJF.mjs.map +7 -0
  5. package/dist/lib/browser/FileMain-WEWTX7QB.mjs +27 -0
  6. package/dist/lib/browser/FileMain-WEWTX7QB.mjs.map +7 -0
  7. package/dist/lib/browser/FileSection-BEUGJ7EI.mjs +24 -0
  8. package/dist/lib/browser/FileSection-BEUGJ7EI.mjs.map +7 -0
  9. package/dist/lib/browser/FileSlide-NYBGZEZS.mjs +21 -0
  10. package/dist/lib/browser/FileSlide-NYBGZEZS.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-2I63TM7M.mjs +27 -0
  12. package/dist/lib/browser/chunk-2I63TM7M.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-STEG7B5Y.mjs +17 -0
  14. package/dist/lib/browser/chunk-STEG7B5Y.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-VI24OYJB.mjs +30 -0
  16. package/dist/lib/browser/chunk-VI24OYJB.mjs.map +7 -0
  17. package/dist/lib/browser/index.mjs +517 -0
  18. package/dist/lib/browser/index.mjs.map +7 -0
  19. package/dist/lib/browser/meta.json +1 -0
  20. package/dist/lib/browser/meta.mjs +9 -0
  21. package/dist/lib/browser/meta.mjs.map +7 -0
  22. package/dist/lib/browser/types/index.mjs +10 -0
  23. package/dist/lib/browser/types/index.mjs.map +7 -0
  24. package/dist/types/src/WnfsPlugin.d.ts +4 -0
  25. package/dist/types/src/WnfsPlugin.d.ts.map +1 -0
  26. package/dist/types/src/blockstore.d.ts +19 -0
  27. package/dist/types/src/blockstore.d.ts.map +1 -0
  28. package/dist/types/src/common.d.ts +11 -0
  29. package/dist/types/src/common.d.ts.map +1 -0
  30. package/dist/types/src/components/FileCard.d.ts +9 -0
  31. package/dist/types/src/components/FileCard.d.ts.map +1 -0
  32. package/dist/types/src/components/FileMain.d.ts +7 -0
  33. package/dist/types/src/components/FileMain.d.ts.map +1 -0
  34. package/dist/types/src/components/FilePreview.d.ts +11 -0
  35. package/dist/types/src/components/FilePreview.d.ts.map +1 -0
  36. package/dist/types/src/components/FileSection.d.ts +8 -0
  37. package/dist/types/src/components/FileSection.d.ts.map +1 -0
  38. package/dist/types/src/components/FileSlide.d.ts +8 -0
  39. package/dist/types/src/components/FileSlide.d.ts.map +1 -0
  40. package/dist/types/src/components/index.d.ts +14 -0
  41. package/dist/types/src/components/index.d.ts.map +1 -0
  42. package/dist/types/src/extensions/image.d.ts +9 -0
  43. package/dist/types/src/extensions/image.d.ts.map +1 -0
  44. package/dist/types/src/extensions/image.stories.d.ts +10 -0
  45. package/dist/types/src/extensions/image.stories.d.ts.map +1 -0
  46. package/dist/types/src/extensions/index.d.ts +2 -0
  47. package/dist/types/src/extensions/index.d.ts.map +1 -0
  48. package/dist/types/src/index.d.ts +4 -0
  49. package/dist/types/src/index.d.ts.map +1 -0
  50. package/dist/types/src/load.d.ts +8 -0
  51. package/dist/types/src/load.d.ts.map +1 -0
  52. package/dist/types/src/meta.d.ts +10 -0
  53. package/dist/types/src/meta.d.ts.map +1 -0
  54. package/dist/types/src/translations.d.ts +11 -0
  55. package/dist/types/src/translations.d.ts.map +1 -0
  56. package/dist/types/src/types/file.d.ts +20 -0
  57. package/dist/types/src/types/file.d.ts.map +1 -0
  58. package/dist/types/src/types/index.d.ts +3 -0
  59. package/dist/types/src/types/index.d.ts.map +1 -0
  60. package/dist/types/src/types/types.d.ts +8 -0
  61. package/dist/types/src/types/types.d.ts.map +1 -0
  62. package/dist/types/src/upload.d.ts +10 -0
  63. package/dist/types/src/upload.d.ts.map +1 -0
  64. package/dist/types/src/wnfs-url.d.ts +2 -0
  65. package/dist/types/src/wnfs-url.d.ts.map +1 -0
  66. package/package.json +82 -0
  67. package/src/WnfsPlugin.tsx +102 -0
  68. package/src/blockstore.ts +96 -0
  69. package/src/common.ts +84 -0
  70. package/src/components/FileCard.tsx +45 -0
  71. package/src/components/FileMain.tsx +28 -0
  72. package/src/components/FilePreview.tsx +23 -0
  73. package/src/components/FileSection.tsx +20 -0
  74. package/src/components/FileSlide.tsx +20 -0
  75. package/src/components/index.ts +11 -0
  76. package/src/extensions/image.stories.tsx +142 -0
  77. package/src/extensions/image.ts +244 -0
  78. package/src/extensions/index.ts +5 -0
  79. package/src/index.ts +9 -0
  80. package/src/load.ts +63 -0
  81. package/src/meta.tsx +15 -0
  82. package/src/translations.ts +17 -0
  83. package/src/types/file.ts +13 -0
  84. package/src/types/index.ts +6 -0
  85. package/src/types/types.ts +27 -0
  86. package/src/upload.ts +46 -0
  87. package/src/wnfs-url.ts +7 -0
@@ -0,0 +1,517 @@
1
+ import {
2
+ FileType
3
+ } from "./chunk-VI24OYJB.mjs";
4
+ import {
5
+ WNFS_PLUGIN,
6
+ meta_default
7
+ } from "./chunk-STEG7B5Y.mjs";
8
+
9
+ // packages/plugins/experimental/plugin-wnfs/src/WnfsPlugin.tsx
10
+ import { FileCloud } from "@phosphor-icons/react";
11
+ import React2 from "react";
12
+ import { isObject, resolvePlugin } from "@dxos/app-framework";
13
+ import { invariant } from "@dxos/invariant";
14
+ import { parseClientPlugin } from "@dxos/plugin-client";
15
+ import { getSpace } from "@dxos/react-client/echo";
16
+ import { isTileComponentProps } from "@dxos/react-ui-mosaic";
17
+
18
+ // packages/plugins/experimental/plugin-wnfs/src/blockstore.ts
19
+ import { BaseBlockstore } from "blockstore-core";
20
+ import { IDBBlockstore } from "blockstore-idb";
21
+
22
+ // packages/plugins/experimental/plugin-wnfs/src/common.ts
23
+ import { CID } from "multiformats/cid";
24
+ import { sha256 } from "multiformats/hashes/sha2";
25
+ import * as crypto from "@dxos/crypto";
26
+ var filePath = (fileName, space) => {
27
+ return [
28
+ "spaces",
29
+ space.properties.id,
30
+ "files",
31
+ fileName
32
+ ];
33
+ };
34
+ var Rng = class {
35
+ randomBytes(count) {
36
+ return new Uint8Array(crypto.randomBytes(count));
37
+ }
38
+ };
39
+ var store = (blockstore) => {
40
+ const getBlock = async (cid) => {
41
+ const decodedCid = CID.decode(cid);
42
+ return await blockstore.get(decodedCid);
43
+ };
44
+ const hasBlock = async (cid) => {
45
+ const decodedCid = CID.decode(cid);
46
+ return await blockstore.has(decodedCid);
47
+ };
48
+ const putBlockKeyed = async (cid, bytes) => {
49
+ const decodedCid = CID.decode(cid);
50
+ await blockstore.put(decodedCid, bytes);
51
+ };
52
+ const putBlock = async (bytes, codec) => {
53
+ const hash = await sha256.digest(bytes);
54
+ const cid = CID.create(1, codec, hash);
55
+ await blockstore.put(cid, bytes);
56
+ return cid.bytes;
57
+ };
58
+ return {
59
+ getBlock,
60
+ hasBlock,
61
+ putBlockKeyed,
62
+ putBlock
63
+ };
64
+ };
65
+ var storeName = () => "dxos/wnfs";
66
+
67
+ // packages/plugins/experimental/plugin-wnfs/src/blockstore.ts
68
+ var create = (apiHost) => {
69
+ return new MixedBlockstore(apiHost);
70
+ };
71
+ var MixedBlockstore = class extends BaseBlockstore {
72
+ #apiHost;
73
+ #idbStore;
74
+ constructor(apiHost) {
75
+ super();
76
+ this.#apiHost = apiHost;
77
+ this.#idbStore = new IDBBlockstore(storeName());
78
+ }
79
+ async open() {
80
+ await this.#idbStore.open();
81
+ }
82
+ url(apiHost, cid) {
83
+ const path = cid ? cid.toString() : "";
84
+ return `${apiHost}/api/file/${path}`;
85
+ }
86
+ // Blockstore implementation
87
+ async delete(key) {
88
+ await this.#idbStore.delete(key);
89
+ if (this.#apiHost) {
90
+ await fetch(this.url(this.#apiHost, key), {
91
+ method: "DELETE"
92
+ });
93
+ }
94
+ }
95
+ async get(key) {
96
+ if (await this.#idbStore.has(key)) {
97
+ return await this.#idbStore.get(key);
98
+ }
99
+ if (this.#apiHost) {
100
+ return await fetch(this.url(this.#apiHost, key), {
101
+ method: "GET"
102
+ }).then((r) => r.arrayBuffer()).then((r) => new Uint8Array(r));
103
+ }
104
+ return await this.#idbStore.get(key);
105
+ }
106
+ async has(key) {
107
+ if (await this.#idbStore.has(key)) {
108
+ return true;
109
+ }
110
+ if (this.#apiHost) {
111
+ return await fetch(this.url(this.#apiHost, key), {
112
+ method: "HEAD"
113
+ }).then((r) => r.ok);
114
+ }
115
+ return false;
116
+ }
117
+ async put(key, val) {
118
+ await this.#idbStore.put(key, val);
119
+ if (this.#apiHost) {
120
+ await fetch(this.url(this.#apiHost, key), {
121
+ method: "POST",
122
+ body: val
123
+ });
124
+ }
125
+ return key;
126
+ }
127
+ async destroy() {
128
+ await this.#idbStore.destroy();
129
+ }
130
+ };
131
+
132
+ // packages/plugins/experimental/plugin-wnfs/src/components/index.ts
133
+ import React from "react";
134
+ var FileCard = React.lazy(() => import("./FileCard-HJIZDWJF.mjs"));
135
+ var FileMain = React.lazy(() => import("./FileMain-WEWTX7QB.mjs"));
136
+ var FileSection = React.lazy(() => import("./FileSection-BEUGJ7EI.mjs"));
137
+ var FileSlide = React.lazy(() => import("./FileSlide-NYBGZEZS.mjs"));
138
+
139
+ // packages/plugins/experimental/plugin-wnfs/src/extensions/image.ts
140
+ import { syntaxTree } from "@codemirror/language";
141
+ import { StateField, StateEffect } from "@codemirror/state";
142
+ import { Decoration, EditorView, WidgetType, ViewPlugin } from "@codemirror/view";
143
+ import { log } from "@dxos/log";
144
+
145
+ // packages/plugins/experimental/plugin-wnfs/src/load.ts
146
+ import { CID as CID2 } from "multiformats";
147
+ import * as Uint8Arrays from "uint8arrays";
148
+ import { AccessKey, PrivateForest, PrivateDirectory, PrivateNode } from "wnfs";
149
+ var loadWnfs = async (space, blockstore) => {
150
+ const exists = space.properties.wnfs_access_key !== void 0 && space.properties.wnfs_private_forest_cid !== void 0;
151
+ return exists ? await loadWnfsDir(blockstore, space) : await createWnfsDir(blockstore, space);
152
+ };
153
+ var createWnfsDir = async (blockstore, space) => {
154
+ const wnfsStore = store(blockstore);
155
+ const rng = new Rng();
156
+ const forest = new PrivateForest(rng);
157
+ const dirResult = await PrivateDirectory.newAndStore(forest.emptyName(), /* @__PURE__ */ new Date(), forest, wnfsStore, rng);
158
+ const dir = dirResult.rootDir;
159
+ const [accessKeyRaw, newForest] = await dir.asNode().store(dirResult.forest, wnfsStore, rng);
160
+ const cidBytes = await newForest.store(wnfsStore);
161
+ space.properties.wnfs_access_key = Uint8Arrays.toString(accessKeyRaw.toBytes(), "base64");
162
+ space.properties.wnfs_private_forest_cid = CID2.decode(cidBytes).toString();
163
+ return {
164
+ directory: dir,
165
+ forest: newForest
166
+ };
167
+ };
168
+ var loadWnfsDir = async (blockstore, space) => {
169
+ const wnfsStore = store(blockstore);
170
+ const accessKey = AccessKey.fromBytes(Uint8Arrays.fromString(space.properties.wnfs_access_key, "base64"));
171
+ const forest = await PrivateForest.load(CID2.parse(space.properties.wnfs_private_forest_cid).bytes, wnfsStore);
172
+ const node = await PrivateNode.load(accessKey, forest, wnfsStore);
173
+ return {
174
+ directory: node.asDir(),
175
+ forest
176
+ };
177
+ };
178
+
179
+ // packages/plugins/experimental/plugin-wnfs/src/extensions/image.ts
180
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-wnfs/src/extensions/image.ts";
181
+ var image = (options) => {
182
+ return [
183
+ stateField(options),
184
+ viewPlugin(options)
185
+ ];
186
+ };
187
+ var loadedWnfsInstances = {};
188
+ var stateEffect = StateEffect.define({});
189
+ var stateField = (options) => StateField.define({
190
+ create: () => {
191
+ return Decoration.none;
192
+ },
193
+ update: (value, tr) => {
194
+ for (const effect of tr.effects) {
195
+ if (effect.is(stateEffect)) {
196
+ return value.map(tr.changes).update({
197
+ filterFrom: effect.value.from,
198
+ filterTo: effect.value.to,
199
+ filter: () => false,
200
+ add: effect.value.decorations
201
+ });
202
+ }
203
+ }
204
+ return value;
205
+ },
206
+ provide: (f) => {
207
+ return EditorView.decorations.from(f);
208
+ }
209
+ });
210
+ var viewPlugin = (options) => ViewPlugin.define((view) => {
211
+ buildDecorations({
212
+ from: 0,
213
+ to: view.state.doc.length,
214
+ state: view.state,
215
+ options
216
+ }).then((decorations) => {
217
+ view.dispatch({
218
+ effects: stateEffect.of({
219
+ decorations,
220
+ from: 0,
221
+ to: view.state.doc.length
222
+ })
223
+ });
224
+ }).catch((err) => {
225
+ throw new Error(err);
226
+ });
227
+ const update = (update2) => {
228
+ if (!update2.docChanged) {
229
+ return;
230
+ }
231
+ const { from, to } = changedRange(update2);
232
+ buildDecorations({
233
+ from,
234
+ to,
235
+ state: view.state,
236
+ options
237
+ }).then((decorations) => {
238
+ view.dispatch({
239
+ effects: stateEffect.of({
240
+ decorations,
241
+ from,
242
+ to
243
+ })
244
+ });
245
+ }).catch((err) => {
246
+ log.catch(err, void 0, {
247
+ F: __dxlog_file,
248
+ L: 107,
249
+ S: void 0,
250
+ C: (f, a) => f(...a)
251
+ });
252
+ });
253
+ };
254
+ return {
255
+ update
256
+ };
257
+ });
258
+ var changedRange = (update) => {
259
+ const cursor = update.state.selection.main.head;
260
+ const oldCursor = update.changes.mapPos(update.startState.selection.main.head);
261
+ let from = Math.min(cursor, oldCursor);
262
+ let to = Math.max(cursor, oldCursor);
263
+ update.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
264
+ from = Math.min(from, fromB);
265
+ to = Math.max(to, toB);
266
+ });
267
+ from = update.state.doc.lineAt(from).from;
268
+ to = update.state.doc.lineAt(to).to;
269
+ return {
270
+ from,
271
+ to
272
+ };
273
+ };
274
+ var buildDecorations = async ({ from, to, state, options }) => {
275
+ const cursor = state.selection.main.head;
276
+ let nodes = [];
277
+ syntaxTree(state).iterate({
278
+ enter: (node) => {
279
+ if (node.name === "Image") {
280
+ const urlNode = node.node.getChild("URL");
281
+ if (urlNode) {
282
+ const hide = state.readOnly || cursor < node.from || cursor > node.to;
283
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
284
+ if (url.startsWith("wnfs://")) {
285
+ nodes.push({
286
+ from: node.from,
287
+ to: node.to,
288
+ hide,
289
+ url
290
+ });
291
+ }
292
+ }
293
+ }
294
+ },
295
+ from,
296
+ to
297
+ });
298
+ nodes = nodes.sort((a, b) => {
299
+ return a.from - b.from;
300
+ });
301
+ const decorations = await nodes.reduce(async (acc, node) => {
302
+ const array = await acc;
303
+ const path = node.url.replace(/^wnfs:\/\//, "").split("/").map((p) => decodeURIComponent(p));
304
+ const spaceIdFromUrl = path[1];
305
+ if (spaceIdFromUrl !== options.space.properties.id) {
306
+ return array;
307
+ }
308
+ const cacheKey = options.space.properties.wnfs_private_forest_cid;
309
+ const { directory, forest } = loadedWnfsInstances[cacheKey] ? loadedWnfsInstances[cacheKey] : await loadWnfs(options.space, options.blockstore);
310
+ loadedWnfsInstances[cacheKey] = {
311
+ directory,
312
+ forest
313
+ };
314
+ const wnfsStore = store(options.blockstore);
315
+ const { result } = await directory.read(path, true, forest, wnfsStore);
316
+ const blob = new Blob([
317
+ result
318
+ ]);
319
+ const blobUrl = URL.createObjectURL(blob);
320
+ return [
321
+ ...array,
322
+ Decoration.replace({
323
+ block: true,
324
+ widget: new WnfsImageWidget(blobUrl)
325
+ }).range(node.hide ? node.from : node.to, node.to)
326
+ ];
327
+ }, Promise.resolve([]));
328
+ return decorations;
329
+ };
330
+ var WnfsImageWidget = class extends WidgetType {
331
+ constructor(_url) {
332
+ super();
333
+ this._url = _url;
334
+ }
335
+ eq(other) {
336
+ return this._url === other._url;
337
+ }
338
+ toDOM(view) {
339
+ const img = document.createElement("img");
340
+ img.setAttribute("loading", "lazy");
341
+ img.setAttribute("src", this._url);
342
+ img.setAttribute("class", "cm-image");
343
+ img.onload = () => img.classList.add("cm-loaded-image");
344
+ return img;
345
+ }
346
+ };
347
+
348
+ // packages/plugins/experimental/plugin-wnfs/src/translations.ts
349
+ var translations_default = [
350
+ {
351
+ "en-US": {
352
+ [WNFS_PLUGIN]: {
353
+ "plugin name": "Files",
354
+ "file title placeholder": "New file",
355
+ "delete object label": "Delete"
356
+ }
357
+ }
358
+ }
359
+ ];
360
+
361
+ // packages/plugins/experimental/plugin-wnfs/src/upload.ts
362
+ import { CID as CID3 } from "multiformats";
363
+ import * as Raw from "multiformats/codecs/raw";
364
+ import { sha256 as sha2562 } from "multiformats/hashes/sha2";
365
+ import { log as log2 } from "@dxos/log";
366
+
367
+ // packages/plugins/experimental/plugin-wnfs/src/wnfs-url.ts
368
+ var wnfsUrl = (filePath2) => {
369
+ return "wnfs://" + filePath2.map((f) => encodeURIComponent(f)).join("/");
370
+ };
371
+
372
+ // packages/plugins/experimental/plugin-wnfs/src/upload.ts
373
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-wnfs/src/upload.ts";
374
+ var upload = async ({ blockstore, file, space }) => {
375
+ const { directory, forest } = await loadWnfs(space, blockstore);
376
+ const wnfsStore = store(blockstore);
377
+ const bytes = new Uint8Array(await file.arrayBuffer());
378
+ const hash = await sha2562.digest(bytes);
379
+ const cid = CID3.create(1, Raw.code, hash);
380
+ const path = filePath(cid.toString(), space);
381
+ const result = await directory.write(path, true, bytes, /* @__PURE__ */ new Date(), forest, wnfsStore, new Rng());
382
+ const [_, updatedForest] = await result.rootDir.store(result.forest, wnfsStore, new Rng());
383
+ const cidBytes = await updatedForest.store(wnfsStore);
384
+ space.properties.wnfs_private_forest_cid = CID3.decode(cidBytes).toString();
385
+ const info = {
386
+ url: wnfsUrl(path)
387
+ };
388
+ log2("upload", {
389
+ file,
390
+ info
391
+ }, {
392
+ F: __dxlog_file2,
393
+ L: 44,
394
+ S: void 0,
395
+ C: (f, a) => f(...a)
396
+ });
397
+ return info;
398
+ };
399
+
400
+ // packages/plugins/experimental/plugin-wnfs/src/WnfsPlugin.tsx
401
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/experimental/plugin-wnfs/src/WnfsPlugin.tsx";
402
+ var WnfsPlugin = () => {
403
+ let blockstore;
404
+ return {
405
+ meta: meta_default,
406
+ ready: async (plugins) => {
407
+ const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
408
+ invariant(client, void 0, {
409
+ F: __dxlog_file3,
410
+ L: 31,
411
+ S: void 0,
412
+ A: [
413
+ "client",
414
+ ""
415
+ ]
416
+ });
417
+ const apiHost = client.config.values.runtime?.services?.edge?.url || "http://localhost:8787";
418
+ blockstore = create(apiHost);
419
+ await blockstore.open();
420
+ },
421
+ provides: {
422
+ translations: translations_default,
423
+ metadata: {
424
+ records: {
425
+ [FileType.typename]: {
426
+ placeholder: [
427
+ "file title placeholder",
428
+ {
429
+ ns: WNFS_PLUGIN
430
+ }
431
+ ],
432
+ icon: (props) => /* @__PURE__ */ React2.createElement(FileCloud, props)
433
+ }
434
+ }
435
+ },
436
+ echo: {
437
+ schema: [
438
+ FileType
439
+ ]
440
+ },
441
+ // TODO(burdon): Add intent to upload file.
442
+ file: {
443
+ upload: async (file, space) => {
444
+ if (!blockstore) {
445
+ throw new Error("Blockstore is not ready yet");
446
+ }
447
+ return await upload({
448
+ blockstore,
449
+ file,
450
+ space
451
+ });
452
+ }
453
+ },
454
+ markdown: {
455
+ extensions: ({ document: document2 }) => {
456
+ if (!blockstore) {
457
+ throw new Error("Blockstore is not ready yet");
458
+ }
459
+ if (document2) {
460
+ const space = getSpace(document2);
461
+ return space ? [
462
+ image({
463
+ blockstore,
464
+ space
465
+ })
466
+ ] : [];
467
+ }
468
+ return [];
469
+ }
470
+ },
471
+ surface: {
472
+ component: ({ data, role, ...props }, forwardedRef) => {
473
+ switch (role) {
474
+ case "main":
475
+ return data.active instanceof FileType ? /* @__PURE__ */ React2.createElement(FileMain, {
476
+ file: data.active
477
+ }) : null;
478
+ case "slide":
479
+ return data.slide instanceof FileType ? /* @__PURE__ */ React2.createElement(FileSlide, {
480
+ file: data.slide,
481
+ cover: false
482
+ }) : null;
483
+ case "section":
484
+ return data.object instanceof FileType ? /* @__PURE__ */ React2.createElement(FileSection, {
485
+ file: data.object
486
+ }) : null;
487
+ case "card": {
488
+ if (isObject(data.content) && typeof data.content.id === "string" && data.content.object instanceof FileType) {
489
+ const cardProps = {
490
+ ...props,
491
+ item: {
492
+ id: data.content.id,
493
+ object: data.content.object
494
+ }
495
+ };
496
+ return isTileComponentProps(cardProps) ? /* @__PURE__ */ React2.createElement(FileCard, {
497
+ ...cardProps,
498
+ ref: forwardedRef
499
+ }) : null;
500
+ }
501
+ break;
502
+ }
503
+ }
504
+ return null;
505
+ }
506
+ }
507
+ }
508
+ };
509
+ };
510
+
511
+ // packages/plugins/experimental/plugin-wnfs/src/index.ts
512
+ var src_default = WnfsPlugin;
513
+ export {
514
+ WnfsPlugin,
515
+ src_default as default
516
+ };
517
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/WnfsPlugin.tsx", "../../../src/blockstore.ts", "../../../src/common.ts", "../../../src/components/index.ts", "../../../src/extensions/image.ts", "../../../src/load.ts", "../../../src/translations.ts", "../../../src/upload.ts", "../../../src/wnfs-url.ts", "../../../src/index.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { FileCloud, type IconProps } from '@phosphor-icons/react';\nimport React, { type Ref } from 'react';\n\nimport { type PluginDefinition, isObject, resolvePlugin } from '@dxos/app-framework';\nimport { invariant } from '@dxos/invariant';\nimport { parseClientPlugin } from '@dxos/plugin-client';\nimport { type DocumentType } from '@dxos/plugin-markdown/types';\nimport { type Space, getSpace } from '@dxos/react-client/echo';\nimport { isTileComponentProps } from '@dxos/react-ui-mosaic';\n\nimport * as Blockstore from './blockstore';\nimport { FileCard, FileMain, FileSection, FileSlide } from './components';\nimport { image as imageExtension } from './extensions';\nimport meta, { WNFS_PLUGIN } from './meta';\nimport translations from './translations';\nimport { FileType } from './types';\nimport { type WnfsPluginProvides } from './types';\nimport { upload } from './upload';\n\nexport const WnfsPlugin = (): PluginDefinition<WnfsPluginProvides> => {\n let blockstore: Blockstore.MixedBlockstore | undefined;\n\n return {\n meta,\n ready: async (plugins) => {\n const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;\n invariant(client);\n const apiHost = client.config.values.runtime?.services?.edge?.url || 'http://localhost:8787';\n blockstore = Blockstore.create(apiHost);\n await blockstore.open();\n },\n provides: {\n translations,\n metadata: {\n records: {\n [FileType.typename]: {\n placeholder: ['file title placeholder', { ns: WNFS_PLUGIN }],\n icon: (props: IconProps) => <FileCloud {...props} />,\n },\n },\n },\n echo: {\n schema: [FileType],\n },\n // TODO(burdon): Add intent to upload file.\n file: {\n upload: async (file: File, space: Space) => {\n if (!blockstore) {\n throw new Error('Blockstore is not ready yet');\n }\n\n return await upload({ blockstore, file, space });\n },\n },\n markdown: {\n extensions: ({ document }: { document?: DocumentType }) => {\n if (!blockstore) {\n throw new Error('Blockstore is not ready yet');\n }\n\n if (document) {\n const space = getSpace(document);\n return space ? [imageExtension({ blockstore, space })] : [];\n }\n\n return [];\n },\n },\n surface: {\n component: ({ data, role, ...props }, forwardedRef) => {\n switch (role) {\n case 'main':\n return data.active instanceof FileType ? <FileMain file={data.active} /> : null;\n case 'slide':\n return data.slide instanceof FileType ? <FileSlide file={data.slide} cover={false} /> : null;\n case 'section':\n return data.object instanceof FileType ? <FileSection file={data.object} /> : null;\n case 'card': {\n if (\n isObject(data.content) &&\n typeof data.content.id === 'string' &&\n data.content.object instanceof FileType\n ) {\n const cardProps = { ...props, item: { id: data.content.id, object: data.content.object } };\n return isTileComponentProps(cardProps) ? (\n <FileCard {...cardProps} ref={forwardedRef as Ref<HTMLDivElement>} />\n ) : null;\n }\n break;\n }\n }\n\n return null;\n },\n },\n },\n };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { BaseBlockstore } from 'blockstore-core';\nimport { IDBBlockstore } from 'blockstore-idb';\nimport type { CID } from 'multiformats';\n\nimport { storeName } from './common';\n\nexport const create = (apiHost?: string) => {\n return new MixedBlockstore(apiHost);\n};\n\n/**\n * A blockstore that communicates with the DXOS blob service,\n * and which uses an indexedDB blockstore as a client cache.\n */\nexport class MixedBlockstore extends BaseBlockstore {\n readonly #apiHost: string | undefined;\n readonly #idbStore: IDBBlockstore;\n\n constructor(apiHost?: string) {\n super();\n\n this.#apiHost = apiHost;\n this.#idbStore = new IDBBlockstore(storeName());\n }\n\n async open() {\n await this.#idbStore.open();\n }\n\n url(apiHost: string, cid?: CID) {\n const path = cid ? cid.toString() : '';\n return `${apiHost}/api/file/${path}`;\n }\n\n // Blockstore implementation\n override async delete(key: CID): Promise<void> {\n await this.#idbStore.delete(key);\n\n if (this.#apiHost) {\n await fetch(this.url(this.#apiHost, key), {\n method: 'DELETE',\n });\n }\n }\n\n override async get(key: CID): Promise<Uint8Array> {\n if (await this.#idbStore.has(key)) {\n return await this.#idbStore.get(key);\n }\n\n if (this.#apiHost) {\n return await fetch(this.url(this.#apiHost, key), {\n method: 'GET',\n })\n .then((r) => r.arrayBuffer())\n .then((r) => new Uint8Array(r));\n }\n\n return await this.#idbStore.get(key);\n }\n\n override async has(key: CID): Promise<boolean> {\n if (await this.#idbStore.has(key)) {\n return true;\n }\n\n if (this.#apiHost) {\n return await fetch(this.url(this.#apiHost, key), {\n method: 'HEAD',\n }).then((r) => r.ok);\n }\n\n return false;\n }\n\n override async put(key: CID, val: Uint8Array): Promise<CID> {\n await this.#idbStore.put(key, val);\n\n if (this.#apiHost) {\n await fetch(this.url(this.#apiHost, key), {\n method: 'POST',\n body: val,\n });\n }\n\n return key;\n }\n\n async destroy(): Promise<void> {\n await this.#idbStore.destroy();\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { Blockstore } from 'interface-blockstore';\nimport { CID } from 'multiformats/cid';\nimport { sha256 } from 'multiformats/hashes/sha2';\nimport { type BlockStore as WnfsBlockStore } from 'wnfs';\n\nimport * as crypto from '@dxos/crypto';\nimport { type Space } from '@dxos/react-client/echo';\n\n//\n// PATH\n//\n\nexport const filePath = (fileName: string, space: Space) => {\n return ['spaces', space.properties.id, 'files', fileName];\n};\n\n//\n// RNG\n//\n\nexport class Rng {\n randomBytes(count: number): Uint8Array {\n return new Uint8Array(crypto.randomBytes(count));\n }\n}\n\n//\n// STORE\n//\n\nexport const store = (blockstore: Blockstore): WnfsBlockStore => {\n const getBlock = async (cid: Uint8Array): Promise<Uint8Array | undefined> => {\n const decodedCid = CID.decode(cid);\n return await blockstore.get(decodedCid);\n };\n\n const hasBlock = async (cid: Uint8Array): Promise<boolean> => {\n const decodedCid = CID.decode(cid);\n return await blockstore.has(decodedCid);\n };\n\n const putBlockKeyed = async (cid: Uint8Array, bytes: Uint8Array): Promise<void> => {\n const decodedCid = CID.decode(cid);\n await blockstore.put(decodedCid, bytes);\n };\n\n // Don't hash blocks with the rs-wnfs default Blake 3, sha256 has better support.\n const putBlock = async (bytes: Uint8Array, codec: number): Promise<Uint8Array> => {\n const hash = await sha256.digest(bytes);\n const cid = CID.create(1, codec, hash);\n await blockstore.put(cid, bytes);\n return cid.bytes;\n };\n\n return { getBlock, hasBlock, putBlockKeyed, putBlock };\n};\n\nexport const storeName = () => 'dxos/wnfs';\n\n//\n// OTHER\n//\n\nexport const readFile = (file: File): Promise<Uint8Array> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (event) => {\n const result = event.target?.result;\n if (result === null || result === undefined || typeof result === 'string') {\n reject(new Error('Expected an ArrayBuffer'));\n return;\n }\n resolve(new Uint8Array(result));\n };\n reader.onerror = (err) => {\n reject(err);\n };\n reader.readAsArrayBuffer(file);\n });\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\n// Lazily load components for content surfaces.\nexport const FileCard = React.lazy(() => import('./FileCard'));\nexport const FileMain = React.lazy(() => import('./FileMain'));\nexport const FileSection = React.lazy(() => import('./FileSection'));\nexport const FileSlide = React.lazy(() => import('./FileSlide'));\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, type Extension, StateField, type Range, StateEffect } from '@codemirror/state';\nimport { Decoration, EditorView, WidgetType, ViewPlugin, type ViewUpdate } from '@codemirror/view';\nimport type { Blockstore } from 'interface-blockstore';\nimport type { PrivateDirectory, PrivateForest } from 'wnfs';\n\nimport { log } from '@dxos/log';\nimport { type Space } from '@dxos/react-client/echo';\n\nimport { store } from '../common';\nimport { loadWnfs } from '../load';\n\nexport type ImageOptions = {\n blockstore: Blockstore;\n space: Space;\n};\n\nexport const image = (options: ImageOptions): Extension[] => {\n return [stateField(options), viewPlugin(options)];\n};\n\n// GLOBAL STATE\n\n/** Indexed by space id */\nconst loadedWnfsInstances: Record<string, { directory: PrivateDirectory; forest: PrivateForest }> = {};\n\n// EFFECT + EXTENSIONS\n\nconst stateEffect = StateEffect.define<{\n decorations: Range<Decoration>[];\n from: number;\n to: number;\n}>({});\n\nconst stateField = (options: ImageOptions) =>\n StateField.define({\n create: () => {\n return Decoration.none;\n },\n update: (value, tr) => {\n for (const effect of tr.effects) {\n if (effect.is(stateEffect)) {\n return value.map(tr.changes).update({\n filterFrom: effect.value.from,\n filterTo: effect.value.to,\n filter: () => false,\n add: effect.value.decorations,\n });\n }\n }\n\n return value;\n },\n provide: (f) => {\n return EditorView.decorations.from(f);\n },\n });\n\nconst viewPlugin = (options: ImageOptions) =>\n ViewPlugin.define((view: EditorView) => {\n // Initial decoration set on document load\n buildDecorations({\n from: 0,\n to: view.state.doc.length,\n state: view.state,\n options,\n })\n .then((decorations) => {\n view.dispatch({\n effects: stateEffect.of({\n decorations,\n from: 0,\n to: view.state.doc.length,\n }),\n });\n })\n .catch((err) => {\n throw new Error(err);\n });\n\n const update = (update: ViewUpdate) => {\n if (!update.docChanged) {\n return;\n }\n\n const { from, to } = changedRange(update);\n buildDecorations({\n from,\n to,\n state: view.state,\n options,\n })\n .then((decorations) => {\n view.dispatch({\n effects: stateEffect.of({\n decorations,\n from,\n to,\n }),\n });\n })\n .catch((err) => {\n log.catch(err);\n });\n };\n\n return { update };\n });\n\n// 🛠️\n\nconst changedRange = (update: ViewUpdate) => {\n // Find range of changes and cursor changes.\n const cursor = update.state.selection.main.head;\n const oldCursor = update.changes.mapPos(update.startState.selection.main.head);\n\n let from = Math.min(cursor, oldCursor);\n let to = Math.max(cursor, oldCursor);\n\n update.changes.iterChangedRanges((fromA, toA, fromB, toB) => {\n from = Math.min(from, fromB);\n to = Math.max(to, toB);\n });\n\n // Expand to cover lines.\n from = update.state.doc.lineAt(from).from;\n to = update.state.doc.lineAt(to).to;\n\n // Fin\n return { from, to };\n};\n\nconst buildDecorations = async ({\n from,\n to,\n state,\n options,\n}: {\n from: number;\n to: number;\n state: EditorState;\n options: ImageOptions;\n}) => {\n const cursor = state.selection.main.head;\n let nodes: { from: number; hide: boolean; to: number; url: string }[] = [];\n\n syntaxTree(state).iterate({\n enter: (node) => {\n if (node.name === 'Image') {\n const urlNode = node.node.getChild('URL');\n if (urlNode) {\n const hide = state.readOnly || cursor < node.from || cursor > node.to;\n const url = state.sliceDoc(urlNode.from, urlNode.to);\n\n if (url.startsWith('wnfs://')) {\n nodes.push({\n from: node.from,\n to: node.to,\n hide,\n url,\n });\n }\n }\n }\n },\n from,\n to,\n });\n\n // Nodes must be sorted by `from`\n nodes = nodes.sort((a, b) => {\n return a.from - b.from;\n });\n\n const decorations = await nodes.reduce(\n async (acc, node) => {\n const array = await acc;\n const path = node.url\n .replace(/^wnfs:\\/\\//, '')\n .split('/')\n .map((p) => decodeURIComponent(p));\n\n // Cannot load images from other spaces\n const spaceIdFromUrl = path[1];\n if (spaceIdFromUrl !== options.space.properties.id) {\n return array;\n }\n\n const cacheKey = options.space.properties.wnfs_private_forest_cid;\n\n const { directory, forest } = loadedWnfsInstances[cacheKey]\n ? loadedWnfsInstances[cacheKey]\n : await loadWnfs(options.space, options.blockstore);\n\n loadedWnfsInstances[cacheKey] = {\n directory,\n forest,\n };\n\n const wnfsStore = store(options.blockstore);\n\n // Load image contents into memory blob\n const { result } = await directory.read(path, true, forest, wnfsStore);\n const blob = new Blob([result]);\n const blobUrl = URL.createObjectURL(blob);\n\n // Create decoration\n return [\n ...array,\n Decoration.replace({\n block: true, // Prevent cursor from entering.\n widget: new WnfsImageWidget(blobUrl),\n }).range(node.hide ? node.from : node.to, node.to),\n ];\n },\n Promise.resolve([] as Range<Decoration>[]),\n );\n\n return decorations;\n};\n\nclass WnfsImageWidget extends WidgetType {\n constructor(readonly _url: string) {\n super();\n }\n\n override eq(other: this) {\n return this._url === (other as any as WnfsImageWidget)._url;\n }\n\n override toDOM(view: EditorView) {\n const img = document.createElement('img');\n img.setAttribute('loading', 'lazy');\n img.setAttribute('src', this._url);\n img.setAttribute('class', 'cm-image');\n // Images are hidden until successfully loaded to avoid flickering effects.\n img.onload = () => img.classList.add('cm-loaded-image');\n return img;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { Blockstore } from 'interface-blockstore';\nimport { CID } from 'multiformats';\nimport * as Uint8Arrays from 'uint8arrays';\nimport { AccessKey, PrivateForest, PrivateDirectory, PrivateNode } from 'wnfs';\n\nimport { type Space } from '@dxos/react-client/echo';\n\nimport { Rng, store } from './common';\n\n//\n// LOAD\n//\n\nexport const loadWnfs = async (space: Space, blockstore: Blockstore) => {\n const exists =\n space.properties.wnfs_access_key !== undefined && space.properties.wnfs_private_forest_cid !== undefined;\n\n return exists ? await loadWnfsDir(blockstore, space) : await createWnfsDir(blockstore, space);\n};\n\n//\n// PRIVATE\n//\n\nconst createWnfsDir = async (blockstore: Blockstore, space: Space) => {\n const wnfsStore = store(blockstore);\n const rng = new Rng();\n const forest = new PrivateForest(rng);\n\n const dirResult = await PrivateDirectory.newAndStore(forest.emptyName(), new Date(), forest, wnfsStore, rng);\n const dir = dirResult.rootDir as PrivateDirectory;\n\n const [accessKeyRaw, newForest]: [AccessKey, PrivateForest] = await dir\n .asNode()\n .store(dirResult.forest as PrivateForest, wnfsStore, rng);\n\n const cidBytes = await newForest.store(wnfsStore);\n\n space.properties.wnfs_access_key = Uint8Arrays.toString(accessKeyRaw.toBytes(), 'base64');\n space.properties.wnfs_private_forest_cid = CID.decode(cidBytes).toString();\n\n return {\n directory: dir,\n forest: newForest,\n };\n};\n\nconst loadWnfsDir = async (blockstore: Blockstore, space: Space) => {\n const wnfsStore = store(blockstore);\n\n const accessKey = AccessKey.fromBytes(Uint8Arrays.fromString(space.properties.wnfs_access_key, 'base64'));\n const forest = await PrivateForest.load(CID.parse(space.properties.wnfs_private_forest_cid).bytes, wnfsStore);\n const node: PrivateNode = await PrivateNode.load(accessKey, forest, wnfsStore);\n\n return {\n directory: node.asDir(),\n forest,\n };\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { WNFS_PLUGIN } from './meta';\n\nexport default [\n {\n 'en-US': {\n [WNFS_PLUGIN]: {\n 'plugin name': 'Files',\n 'file title placeholder': 'New file',\n 'delete object label': 'Delete',\n },\n },\n },\n];\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { Blockstore } from 'interface-blockstore';\nimport { CID } from 'multiformats';\nimport * as Raw from 'multiformats/codecs/raw';\nimport { sha256 } from 'multiformats/hashes/sha2';\n\nimport type { Space } from '@dxos/client/echo';\nimport { log } from '@dxos/log';\n\nimport { Rng, filePath, store } from './common';\nimport { loadWnfs } from './load';\nimport { wnfsUrl } from './wnfs-url';\n\nexport const upload = async ({ blockstore, file, space }: { blockstore: Blockstore; file: File; space: Space }) => {\n const { directory, forest } = await loadWnfs(space, blockstore);\n const wnfsStore = store(blockstore);\n\n const bytes = new Uint8Array(await file.arrayBuffer());\n const hash = await sha256.digest(bytes);\n const cid = CID.create(1, Raw.code, hash);\n\n const path = filePath(cid.toString(), space);\n\n // Given the root directory of the private file system,\n // write the file contents to `path` in said directory.\n const result = await directory.write(path, true, bytes, new Date(), forest, wnfsStore, new Rng());\n\n // Given the new immutable instance of the root directory after writing to it,\n // **store** the changes in the \"dark forest\" and the associated (block) store.\n const [_, updatedForest] = await result.rootDir.store(result.forest, wnfsStore, new Rng());\n const cidBytes = await updatedForest.store(wnfsStore);\n\n // Update the forest pointer on the associated space.\n space.properties.wnfs_private_forest_cid = CID.decode(cidBytes).toString();\n\n // Generate `wnfs://` URL & return the info.\n const info = {\n url: wnfsUrl(path),\n };\n\n log('upload', { file, info });\n return info;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport const wnfsUrl = (filePath: string[]) => {\n return 'wnfs://' + filePath.map((f) => encodeURIComponent(f)).join('/');\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { WnfsPlugin } from './WnfsPlugin';\n\nexport default WnfsPlugin;\n\nexport * from './WnfsPlugin';\n"],
5
+ "mappings": "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",
6
+ "names": ["FileCloud", "React", "isObject", "resolvePlugin", "invariant", "parseClientPlugin", "getSpace", "isTileComponentProps", "BaseBlockstore", "IDBBlockstore", "CID", "sha256", "crypto", "filePath", "fileName", "space", "properties", "id", "Rng", "randomBytes", "count", "Uint8Array", "store", "blockstore", "getBlock", "cid", "decodedCid", "CID", "decode", "get", "hasBlock", "has", "putBlockKeyed", "bytes", "put", "putBlock", "codec", "hash", "sha256", "digest", "create", "storeName", "create", "apiHost", "MixedBlockstore", "BaseBlockstore", "constructor", "IDBBlockstore", "storeName", "open", "url", "cid", "path", "toString", "delete", "key", "fetch", "method", "get", "has", "then", "r", "arrayBuffer", "Uint8Array", "ok", "put", "val", "body", "destroy", "React", "FileCard", "React", "lazy", "FileMain", "FileSection", "FileSlide", "syntaxTree", "StateField", "StateEffect", "Decoration", "EditorView", "WidgetType", "ViewPlugin", "log", "CID", "Uint8Arrays", "AccessKey", "PrivateForest", "PrivateDirectory", "PrivateNode", "loadWnfs", "space", "blockstore", "exists", "properties", "wnfs_access_key", "undefined", "wnfs_private_forest_cid", "loadWnfsDir", "createWnfsDir", "wnfsStore", "store", "rng", "Rng", "forest", "PrivateForest", "dirResult", "PrivateDirectory", "newAndStore", "emptyName", "Date", "dir", "rootDir", "accessKeyRaw", "newForest", "asNode", "cidBytes", "toString", "toBytes", "CID", "decode", "directory", "accessKey", "AccessKey", "fromBytes", "fromString", "load", "parse", "bytes", "node", "PrivateNode", "asDir", "image", "options", "stateField", "viewPlugin", "loadedWnfsInstances", "stateEffect", "StateEffect", "define", "StateField", "create", "Decoration", "none", "update", "value", "tr", "effect", "effects", "is", "map", "changes", "filterFrom", "from", "filterTo", "to", "filter", "add", "decorations", "provide", "f", "EditorView", "ViewPlugin", "view", "buildDecorations", "state", "doc", "length", "then", "dispatch", "of", "catch", "err", "Error", "docChanged", "changedRange", "log", "cursor", "selection", "main", "head", "oldCursor", "mapPos", "startState", "Math", "min", "max", "iterChangedRanges", "fromA", "toA", "fromB", "toB", "lineAt", "nodes", "syntaxTree", "iterate", "enter", "node", "name", "urlNode", "getChild", "hide", "readOnly", "url", "sliceDoc", "startsWith", "push", "sort", "a", "b", "reduce", "acc", "array", "path", "replace", "split", "p", "decodeURIComponent", "spaceIdFromUrl", "space", "properties", "id", "cacheKey", "wnfs_private_forest_cid", "directory", "forest", "loadWnfs", "blockstore", "wnfsStore", "store", "result", "read", "blob", "Blob", "blobUrl", "URL", "createObjectURL", "block", "widget", "WnfsImageWidget", "range", "Promise", "resolve", "WidgetType", "constructor", "_url", "eq", "other", "toDOM", "img", "document", "createElement", "setAttribute", "onload", "classList", "WNFS_PLUGIN", "CID", "Raw", "sha256", "log", "wnfsUrl", "filePath", "map", "f", "encodeURIComponent", "join", "upload", "blockstore", "file", "space", "directory", "forest", "loadWnfs", "wnfsStore", "store", "bytes", "Uint8Array", "arrayBuffer", "hash", "sha256", "digest", "cid", "CID", "create", "code", "path", "filePath", "toString", "result", "write", "Date", "Rng", "_", "updatedForest", "rootDir", "cidBytes", "properties", "wnfs_private_forest_cid", "decode", "info", "url", "wnfsUrl", "log", "WnfsPlugin", "blockstore", "meta", "ready", "plugins", "client", "resolvePlugin", "parseClientPlugin", "provides", "invariant", "apiHost", "config", "values", "runtime", "services", "edge", "url", "create", "open", "translations", "metadata", "records", "FileType", "typename", "placeholder", "ns", "WNFS_PLUGIN", "icon", "props", "React", "FileCloud", "echo", "schema", "file", "upload", "space", "Error", "markdown", "extensions", "document", "getSpace", "imageExtension", "surface", "component", "data", "role", "forwardedRef", "active", "FileMain", "slide", "FileSlide", "cover", "object", "FileSection", "isObject", "content", "id", "cardProps", "item", "isTileComponentProps", "FileCard", "ref", "WnfsPlugin"]
7
+ }