@dxos/plugin-wnfs 0.8.4-main.c85a9c8dae → 0.8.4-main.d9fc60f731
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/LICENSE +102 -5
- package/PLUGIN.mdl +371 -0
- package/README.md +2 -2
- package/dist/lib/neutral/WnfsPlugin.mjs +51 -0
- package/dist/lib/neutral/WnfsPlugin.mjs.map +7 -0
- package/dist/lib/neutral/WnfsPlugin.node.mjs +12 -0
- package/dist/lib/neutral/WnfsPlugin.node.mjs.map +7 -0
- package/dist/lib/neutral/WnfsPlugin.workerd.mjs +12 -0
- package/dist/lib/neutral/WnfsPlugin.workerd.mjs.map +7 -0
- package/dist/lib/neutral/backend-4HPTHS33.mjs +47 -0
- package/dist/lib/neutral/backend-4HPTHS33.mjs.map +7 -0
- package/dist/lib/{browser/blockstore-Q66HQJ4Q.mjs → neutral/blockstore-U6SPNL2C.mjs} +7 -8
- package/dist/lib/neutral/blockstore-U6SPNL2C.mjs.map +7 -0
- package/dist/lib/neutral/capabilities/index.mjs +13 -0
- package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/neutral/chunk-KUQHRT52.mjs +39 -0
- package/dist/lib/neutral/chunk-KUQHRT52.mjs.map +7 -0
- package/dist/lib/{browser/chunk-UC4HMNZZ.mjs → neutral/chunk-L33MOD23.mjs} +80 -30
- package/dist/lib/neutral/chunk-L33MOD23.mjs.map +7 -0
- package/dist/lib/neutral/chunk-QODCKFTY.mjs +19 -0
- package/dist/lib/neutral/chunk-QODCKFTY.mjs.map +7 -0
- package/dist/lib/neutral/helpers/index.mjs +26 -0
- package/dist/lib/neutral/helpers/index.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +36 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/meta.mjs +8 -0
- package/dist/lib/neutral/meta.mjs.map +7 -0
- package/dist/lib/neutral/plugin.mjs +12 -0
- package/dist/lib/neutral/plugin.mjs.map +7 -0
- package/dist/lib/neutral/translations.mjs +17 -0
- package/dist/lib/neutral/translations.mjs.map +7 -0
- package/dist/lib/neutral/types/index.mjs +8 -0
- package/dist/lib/neutral/types/index.mjs.map +7 -0
- package/dist/lib/neutral/url-resolver-BIRH7WHL.mjs +47 -0
- package/dist/lib/neutral/url-resolver-BIRH7WHL.mjs.map +7 -0
- package/dist/types/src/WnfsPlugin.d.ts +1 -0
- package/dist/types/src/WnfsPlugin.d.ts.map +1 -1
- package/dist/types/src/WnfsPlugin.node.d.ts +4 -0
- package/dist/types/src/WnfsPlugin.node.d.ts.map +1 -0
- package/dist/types/src/WnfsPlugin.test.d.ts +2 -0
- package/dist/types/src/WnfsPlugin.test.d.ts.map +1 -0
- package/dist/types/src/WnfsPlugin.workerd.d.ts +4 -0
- package/dist/types/src/WnfsPlugin.workerd.d.ts.map +1 -0
- package/dist/types/src/annotations.d.ts +7 -0
- package/dist/types/src/annotations.d.ts.map +1 -0
- package/dist/types/src/blockstore.d.ts.map +1 -1
- package/dist/types/src/capabilities/backend.d.ts +7 -0
- package/dist/types/src/capabilities/backend.d.ts.map +1 -0
- package/dist/types/src/capabilities/blockstore.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +5 -5
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/url-resolver.d.ts +7 -0
- package/dist/types/src/capabilities/url-resolver.d.ts.map +1 -0
- package/dist/types/src/helpers/common.d.ts.map +1 -1
- package/dist/types/src/helpers/load.d.ts +1 -1
- package/dist/types/src/helpers/load.d.ts.map +1 -1
- package/dist/types/src/helpers/upload.d.ts +1 -1
- package/dist/types/src/helpers/upload.d.ts.map +1 -1
- package/dist/types/src/helpers/wnfs-url.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +3 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/plugin.d.ts +3 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +2 -15
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/WnfsCapabilities.d.ts +11 -0
- package/dist/types/src/types/WnfsCapabilities.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +1 -3
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +77 -48
- package/src/WnfsPlugin.node.ts +11 -0
- package/src/WnfsPlugin.test.ts +20 -0
- package/src/WnfsPlugin.tsx +16 -41
- package/src/WnfsPlugin.workerd.ts +11 -0
- package/src/annotations.ts +16 -0
- package/src/blockstore.ts +1 -1
- package/src/capabilities/backend.ts +43 -0
- package/src/capabilities/{blockstore/blockstore.ts → blockstore.ts} +3 -2
- package/src/capabilities/index.ts +14 -5
- package/src/capabilities/url-resolver.ts +44 -0
- package/src/helpers/load.ts +33 -19
- package/src/helpers/upload.ts +13 -4
- package/src/index.ts +3 -2
- package/src/meta.ts +22 -6
- package/src/plugin.ts +9 -0
- package/src/translations.ts +2 -14
- package/src/types/WnfsCapabilities.ts +18 -0
- package/src/types/index.ts +1 -3
- package/src/vite-env.d.ts +10 -0
- package/dist/lib/browser/FileContainer-EILNV5LV.mjs +0 -74
- package/dist/lib/browser/FileContainer-EILNV5LV.mjs.map +0 -7
- package/dist/lib/browser/blockstore-Q66HQJ4Q.mjs.map +0 -7
- package/dist/lib/browser/chunk-BXGCJRL2.mjs +0 -155
- package/dist/lib/browser/chunk-BXGCJRL2.mjs.map +0 -7
- package/dist/lib/browser/chunk-HXVPBJ3A.mjs +0 -56
- package/dist/lib/browser/chunk-HXVPBJ3A.mjs.map +0 -7
- package/dist/lib/browser/chunk-UC4HMNZZ.mjs.map +0 -7
- package/dist/lib/browser/file-uploader-QL4DTOMM.mjs +0 -35
- package/dist/lib/browser/file-uploader-QL4DTOMM.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -117
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/markdown-AYCVG6TJ.mjs +0 -201
- package/dist/lib/browser/markdown-AYCVG6TJ.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/operation-resolver-YYWUF6EY.mjs +0 -99
- package/dist/lib/browser/operation-resolver-YYWUF6EY.mjs.map +0 -7
- package/dist/lib/browser/react-surface-3LKVDPH7.mjs +0 -60
- package/dist/lib/browser/react-surface-3LKVDPH7.mjs.map +0 -7
- package/dist/lib/browser/types/index.mjs +0 -13
- package/dist/types/src/capabilities/blockstore/blockstore.d.ts.map +0 -1
- package/dist/types/src/capabilities/blockstore/index.d.ts +0 -3
- package/dist/types/src/capabilities/blockstore/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/file-uploader/file-uploader.d.ts +0 -6
- package/dist/types/src/capabilities/file-uploader/file-uploader.d.ts.map +0 -1
- package/dist/types/src/capabilities/file-uploader/index.d.ts +0 -3
- package/dist/types/src/capabilities/file-uploader/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/markdown/index.d.ts +0 -3
- package/dist/types/src/capabilities/markdown/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/markdown/markdown.d.ts +0 -5
- package/dist/types/src/capabilities/markdown/markdown.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +0 -5
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
- package/dist/types/src/components/FileInput.d.ts +0 -8
- package/dist/types/src/components/FileInput.d.ts.map +0 -1
- package/dist/types/src/components/FilePreview.d.ts +0 -11
- package/dist/types/src/components/FilePreview.d.ts.map +0 -1
- package/dist/types/src/components/index.d.ts +0 -3
- package/dist/types/src/components/index.d.ts.map +0 -1
- package/dist/types/src/containers/FileContainer/FileContainer.d.ts +0 -7
- package/dist/types/src/containers/FileContainer/FileContainer.d.ts.map +0 -1
- package/dist/types/src/containers/FileContainer/index.d.ts +0 -3
- package/dist/types/src/containers/FileContainer/index.d.ts.map +0 -1
- package/dist/types/src/containers/index.d.ts +0 -3
- package/dist/types/src/containers/index.d.ts.map +0 -1
- package/dist/types/src/extensions/image.d.ts +0 -14
- package/dist/types/src/extensions/image.d.ts.map +0 -1
- package/dist/types/src/extensions/image.stories.d.ts +0 -11
- package/dist/types/src/extensions/image.stories.d.ts.map +0 -1
- package/dist/types/src/extensions/index.d.ts +0 -2
- package/dist/types/src/extensions/index.d.ts.map +0 -1
- package/dist/types/src/types/File.d.ts +0 -16
- package/dist/types/src/types/File.d.ts.map +0 -1
- package/dist/types/src/types/capabilities.d.ts +0 -13
- package/dist/types/src/types/capabilities.d.ts.map +0 -1
- package/dist/types/src/types/types.d.ts +0 -112
- package/dist/types/src/types/types.d.ts.map +0 -1
- package/src/capabilities/blockstore/index.ts +0 -7
- package/src/capabilities/file-uploader/file-uploader.ts +0 -34
- package/src/capabilities/file-uploader/index.ts +0 -7
- package/src/capabilities/markdown/index.ts +0 -7
- package/src/capabilities/markdown/markdown.ts +0 -33
- package/src/capabilities/operation-resolver/index.ts +0 -7
- package/src/capabilities/operation-resolver/operation-resolver.ts +0 -62
- package/src/capabilities/react-surface/index.ts +0 -7
- package/src/capabilities/react-surface/react-surface.tsx +0 -51
- package/src/components/FileInput.tsx +0 -47
- package/src/components/FilePreview.tsx +0 -23
- package/src/components/index.ts +0 -6
- package/src/containers/FileContainer/FileContainer.tsx +0 -58
- package/src/containers/FileContainer/index.ts +0 -7
- package/src/containers/index.ts +0 -7
- package/src/extensions/image.stories.tsx +0 -104
- package/src/extensions/image.tsx +0 -203
- package/src/extensions/index.ts +0 -5
- package/src/types/File.ts +0 -24
- package/src/types/capabilities.ts +0 -18
- package/src/types/types.ts +0 -81
- /package/dist/lib/{browser/types/index.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
- /package/dist/types/src/capabilities/{blockstore/blockstore.d.ts → blockstore.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-wnfs",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.d9fc60f731",
|
|
4
4
|
"description": "WNFS file management plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -8,86 +8,115 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/dxos/dxos"
|
|
10
10
|
},
|
|
11
|
-
"license": "
|
|
11
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
12
12
|
"author": "DXOS.org",
|
|
13
|
+
"sideEffects": true,
|
|
13
14
|
"type": "module",
|
|
15
|
+
"imports": {
|
|
16
|
+
"#capabilities": {
|
|
17
|
+
"source": "./src/capabilities/index.ts",
|
|
18
|
+
"types": "./dist/types/src/capabilities/index.d.ts",
|
|
19
|
+
"default": "./dist/lib/neutral/capabilities/index.mjs"
|
|
20
|
+
},
|
|
21
|
+
"#helpers": {
|
|
22
|
+
"source": "./src/helpers/index.ts",
|
|
23
|
+
"types": "./dist/types/src/helpers/index.d.ts",
|
|
24
|
+
"default": "./dist/lib/neutral/helpers/index.mjs"
|
|
25
|
+
},
|
|
26
|
+
"#meta": {
|
|
27
|
+
"source": "./src/meta.ts",
|
|
28
|
+
"types": "./dist/types/src/meta.d.ts",
|
|
29
|
+
"default": "./dist/lib/neutral/meta.mjs"
|
|
30
|
+
},
|
|
31
|
+
"#plugin": {
|
|
32
|
+
"source": {
|
|
33
|
+
"workerd": "./src/WnfsPlugin.workerd.ts",
|
|
34
|
+
"node": "./src/WnfsPlugin.node.ts",
|
|
35
|
+
"default": "./src/WnfsPlugin.tsx"
|
|
36
|
+
},
|
|
37
|
+
"types": "./dist/types/src/WnfsPlugin.d.ts",
|
|
38
|
+
"workerd": "./dist/lib/neutral/WnfsPlugin.workerd.mjs",
|
|
39
|
+
"node": "./dist/lib/neutral/WnfsPlugin.node.mjs",
|
|
40
|
+
"default": "./dist/lib/neutral/WnfsPlugin.mjs"
|
|
41
|
+
},
|
|
42
|
+
"#translations": {
|
|
43
|
+
"source": "./src/translations.ts",
|
|
44
|
+
"types": "./dist/types/src/translations.d.ts",
|
|
45
|
+
"default": "./dist/lib/neutral/translations.mjs"
|
|
46
|
+
},
|
|
47
|
+
"#types": {
|
|
48
|
+
"source": "./src/types/index.ts",
|
|
49
|
+
"types": "./dist/types/src/types/index.d.ts",
|
|
50
|
+
"default": "./dist/lib/neutral/types/index.mjs"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
14
53
|
"exports": {
|
|
15
54
|
".": {
|
|
16
55
|
"source": "./src/index.ts",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
56
|
+
"types": "./dist/types/src/index.d.ts",
|
|
57
|
+
"default": "./dist/lib/neutral/index.mjs"
|
|
19
58
|
},
|
|
20
|
-
"./
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"types": "./dist/types/src/
|
|
59
|
+
"./assets/PLUGIN.mdl": "./PLUGIN.mdl",
|
|
60
|
+
"./plugin": {
|
|
61
|
+
"source": "./src/plugin.ts",
|
|
62
|
+
"types": "./dist/types/src/plugin.d.ts",
|
|
63
|
+
"default": "./dist/lib/neutral/plugin.mjs"
|
|
64
|
+
},
|
|
65
|
+
"./translations": {
|
|
66
|
+
"source": "./src/translations.ts",
|
|
67
|
+
"types": "./dist/types/src/translations.d.ts",
|
|
68
|
+
"default": "./dist/lib/neutral/translations.mjs"
|
|
24
69
|
}
|
|
25
70
|
},
|
|
26
71
|
"types": "dist/types/src/index.d.ts",
|
|
27
|
-
"typesVersions": {
|
|
28
|
-
"*": {
|
|
29
|
-
"types": [
|
|
30
|
-
"dist/types/src/types/index.d.ts"
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
72
|
"files": [
|
|
35
73
|
"dist",
|
|
36
|
-
"src"
|
|
74
|
+
"src",
|
|
75
|
+
"PLUGIN.mdl"
|
|
37
76
|
],
|
|
38
77
|
"dependencies": {
|
|
39
|
-
"@codemirror/language": "^6.11.3",
|
|
40
|
-
"@codemirror/state": "^6.5.2",
|
|
41
|
-
"@codemirror/view": "^6.38.4",
|
|
42
78
|
"@ipld/car": "^5.3.3",
|
|
43
79
|
"blockstore-core": "^5.0.1",
|
|
44
80
|
"blockstore-idb": "^2.0.0",
|
|
45
81
|
"debounce": "^2.2.0",
|
|
46
|
-
"effect": "3.
|
|
82
|
+
"effect": "3.21.2",
|
|
47
83
|
"idb-keyval": "^6.2.1",
|
|
48
84
|
"interface-blockstore": "^5.2.10",
|
|
49
85
|
"it-all": "^3.0.6",
|
|
50
86
|
"multiformats": "^13.2.2",
|
|
51
|
-
"react-dropzone": "^14.2.3",
|
|
52
87
|
"uint8arrays": "^5.1.0",
|
|
53
88
|
"wnfs": "0.2.2",
|
|
54
|
-
"@dxos/app-
|
|
55
|
-
"@dxos/app-
|
|
56
|
-
"@dxos/crypto": "0.8.4-main.
|
|
57
|
-
"@dxos/
|
|
58
|
-
"@dxos/
|
|
59
|
-
"@dxos/
|
|
60
|
-
"@dxos/
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/plugin-
|
|
63
|
-
"@dxos/
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/react-ui-form": "0.8.4-main.c85a9c8dae",
|
|
68
|
-
"@dxos/react-ui-editor": "0.8.4-main.c85a9c8dae",
|
|
69
|
-
"@dxos/schema": "0.8.4-main.c85a9c8dae",
|
|
70
|
-
"@dxos/ui-editor": "0.8.4-main.c85a9c8dae",
|
|
71
|
-
"@dxos/util": "0.8.4-main.c85a9c8dae",
|
|
72
|
-
"@dxos/react-ui-stack": "0.8.4-main.c85a9c8dae",
|
|
73
|
-
"@dxos/react-ui-mosaic": "0.8.4-main.c85a9c8dae"
|
|
89
|
+
"@dxos/app-toolkit": "0.8.4-main.d9fc60f731",
|
|
90
|
+
"@dxos/app-framework": "0.8.4-main.d9fc60f731",
|
|
91
|
+
"@dxos/crypto": "0.8.4-main.d9fc60f731",
|
|
92
|
+
"@dxos/echo": "0.8.4-main.d9fc60f731",
|
|
93
|
+
"@dxos/invariant": "0.8.4-main.d9fc60f731",
|
|
94
|
+
"@dxos/keys": "0.8.4-main.d9fc60f731",
|
|
95
|
+
"@dxos/log": "0.8.4-main.d9fc60f731",
|
|
96
|
+
"@dxos/plugin-file": "0.8.4-main.d9fc60f731",
|
|
97
|
+
"@dxos/plugin-client": "0.8.4-main.d9fc60f731",
|
|
98
|
+
"@dxos/react-client": "0.8.4-main.d9fc60f731",
|
|
99
|
+
"@dxos/react-ui": "0.8.4-main.d9fc60f731",
|
|
100
|
+
"@dxos/types": "0.8.4-main.d9fc60f731",
|
|
101
|
+
"@dxos/util": "0.8.4-main.d9fc60f731"
|
|
74
102
|
},
|
|
75
103
|
"devDependencies": {
|
|
76
104
|
"@types/react": "~19.2.7",
|
|
77
105
|
"@types/react-dom": "~19.2.3",
|
|
78
106
|
"react": "~19.2.3",
|
|
79
107
|
"react-dom": "~19.2.3",
|
|
80
|
-
"vite": "^
|
|
81
|
-
"@dxos/
|
|
82
|
-
"@dxos/
|
|
83
|
-
"@dxos/
|
|
108
|
+
"vite": "^8.0.14",
|
|
109
|
+
"@dxos/plugin-testing": "0.8.4-main.d9fc60f731",
|
|
110
|
+
"@dxos/random": "0.8.4-main.d9fc60f731",
|
|
111
|
+
"@dxos/storybook-utils": "0.8.4-main.d9fc60f731",
|
|
112
|
+
"@dxos/ui-theme": "0.8.4-main.d9fc60f731"
|
|
84
113
|
},
|
|
85
114
|
"peerDependencies": {
|
|
86
|
-
"effect": "3.
|
|
115
|
+
"effect": "3.21.2",
|
|
87
116
|
"react": "~19.2.3",
|
|
88
117
|
"react-dom": "~19.2.3",
|
|
89
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
90
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
118
|
+
"@dxos/react-ui": "0.8.4-main.d9fc60f731",
|
|
119
|
+
"@dxos/ui-theme": "0.8.4-main.d9fc60f731"
|
|
91
120
|
},
|
|
92
121
|
"publishConfig": {
|
|
93
122
|
"access": "public"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { ClientPlugin } from '@dxos/plugin-client/plugin';
|
|
8
|
+
import { createComposerTestApp } from '@dxos/plugin-testing/harness';
|
|
9
|
+
|
|
10
|
+
import { WnfsPlugin } from '#plugin';
|
|
11
|
+
|
|
12
|
+
describe('WnfsPlugin', () => {
|
|
13
|
+
test('activates without errors', async ({ expect }) => {
|
|
14
|
+
await using harness = await createComposerTestApp({
|
|
15
|
+
plugins: [ClientPlugin({}), WnfsPlugin()],
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
expect(harness.manager.getActive()).toBeInstanceOf(Array);
|
|
19
|
+
});
|
|
20
|
+
});
|
package/src/WnfsPlugin.tsx
CHANGED
|
@@ -6,37 +6,17 @@ import * as Effect from 'effect/Effect';
|
|
|
6
6
|
|
|
7
7
|
import { Capability, Plugin } from '@dxos/app-framework';
|
|
8
8
|
import { AppPlugin } from '@dxos/app-toolkit';
|
|
9
|
-
import { Operation } from '@dxos/operation';
|
|
10
9
|
import { ClientEvents } from '@dxos/plugin-client';
|
|
11
|
-
import { MarkdownEvents } from '@dxos/plugin-markdown';
|
|
12
|
-
import { SpaceCapabilities, SpaceEvents } from '@dxos/plugin-space';
|
|
13
|
-
import { type CreateObject } from '@dxos/plugin-space/types';
|
|
14
10
|
|
|
15
|
-
import {
|
|
16
|
-
import { meta } from '
|
|
17
|
-
import { translations } from '
|
|
18
|
-
import {
|
|
11
|
+
import { Backend, Blockstore, UrlResolver } from '#capabilities';
|
|
12
|
+
import { meta } from '#meta';
|
|
13
|
+
import { translations } from '#translations';
|
|
14
|
+
import { WnfsCapabilities } from '#types';
|
|
15
|
+
|
|
16
|
+
// eslint-disable-next-line import/no-relative-packages
|
|
17
|
+
import pluginSpec from '../PLUGIN.mdl?raw';
|
|
19
18
|
|
|
20
19
|
export const WnfsPlugin = Plugin.define(meta).pipe(
|
|
21
|
-
AppPlugin.addMetadataModule({
|
|
22
|
-
metadata: {
|
|
23
|
-
id: WnfsFile.File.typename,
|
|
24
|
-
metadata: {
|
|
25
|
-
// TODO(wittjosiah): Would be nice if icon could change based on the type of the file.
|
|
26
|
-
icon: 'ph--file--regular',
|
|
27
|
-
iconHue: 'teal',
|
|
28
|
-
inputSchema: WnfsAction.UploadFileSchema,
|
|
29
|
-
createObject: ((props, { db }) =>
|
|
30
|
-
Effect.gen(function* () {
|
|
31
|
-
const { object } = yield* Operation.invoke(WnfsOperation.CreateFile, { ...props, db });
|
|
32
|
-
return object;
|
|
33
|
-
})) satisfies CreateObject,
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
}),
|
|
37
|
-
AppPlugin.addOperationResolverModule({ activate: OperationResolver }),
|
|
38
|
-
AppPlugin.addSchemaModule({ schema: [WnfsFile.File] }),
|
|
39
|
-
AppPlugin.addSurfaceModule({ activate: ReactSurface }),
|
|
40
20
|
AppPlugin.addTranslationsModule({ translations }),
|
|
41
21
|
Plugin.addModule({
|
|
42
22
|
id: 'blockstore',
|
|
@@ -53,24 +33,19 @@ export const WnfsPlugin = Plugin.define(meta).pipe(
|
|
|
53
33
|
}),
|
|
54
34
|
}),
|
|
55
35
|
Plugin.addModule({
|
|
56
|
-
id: '
|
|
57
|
-
activatesOn:
|
|
58
|
-
activate:
|
|
59
|
-
Effect.succeed(
|
|
60
|
-
Capability.contributes(SpaceCapabilities.OnCreateSpace, (params) =>
|
|
61
|
-
Operation.invoke(WnfsOperation.OnCreateSpace, params),
|
|
62
|
-
),
|
|
63
|
-
),
|
|
36
|
+
id: 'backend',
|
|
37
|
+
activatesOn: ClientEvents.ClientReady,
|
|
38
|
+
activate: Backend,
|
|
64
39
|
}),
|
|
65
40
|
Plugin.addModule({
|
|
66
|
-
id: '
|
|
41
|
+
id: 'url-resolver',
|
|
67
42
|
activatesOn: ClientEvents.ClientReady,
|
|
68
|
-
activate:
|
|
43
|
+
activate: UrlResolver,
|
|
69
44
|
}),
|
|
70
|
-
|
|
71
|
-
id: '
|
|
72
|
-
activatesOn: MarkdownEvents.SetupExtensions,
|
|
73
|
-
activate: Markdown,
|
|
45
|
+
AppPlugin.addPluginAssetModule({
|
|
46
|
+
asset: { pluginId: meta.id, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
|
|
74
47
|
}),
|
|
75
48
|
Plugin.make,
|
|
76
49
|
);
|
|
50
|
+
|
|
51
|
+
export default WnfsPlugin;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
|
|
7
|
+
import { Annotation } from '@dxos/echo';
|
|
8
|
+
|
|
9
|
+
/** WNFS filesystem state stored on space properties meta. */
|
|
10
|
+
export const WnfsStateAnnotation = Annotation.make({
|
|
11
|
+
id: 'org.dxos.plugin.wnfs.state',
|
|
12
|
+
schema: Schema.Struct({
|
|
13
|
+
accessKey: Schema.String,
|
|
14
|
+
privateForestCid: Schema.String,
|
|
15
|
+
}),
|
|
16
|
+
});
|
package/src/blockstore.ts
CHANGED
|
@@ -145,7 +145,7 @@ export class MixedBlockstore extends BaseBlockstore {
|
|
|
145
145
|
|
|
146
146
|
// QUEUE
|
|
147
147
|
|
|
148
|
-
readonly queueCacheName = `${storeName()}
|
|
148
|
+
readonly queueCacheName = `${storeName()}.state.queue`;
|
|
149
149
|
|
|
150
150
|
async #addToQueue(key: CID): Promise<void> {
|
|
151
151
|
await this.#saveQueue([...this.#queue, key.toString()]);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Capability } from '@dxos/app-framework';
|
|
8
|
+
import { invariant } from '@dxos/invariant';
|
|
9
|
+
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
10
|
+
import { FileCapabilities } from '@dxos/plugin-file/types';
|
|
11
|
+
import { File } from '@dxos/types';
|
|
12
|
+
|
|
13
|
+
import { WnfsCapabilities } from '#types';
|
|
14
|
+
|
|
15
|
+
import { upload } from '../helpers';
|
|
16
|
+
|
|
17
|
+
export const WNFS_BACKEND_ID = 'wnfs';
|
|
18
|
+
|
|
19
|
+
export default Capability.makeModule(
|
|
20
|
+
Effect.fnUntraced(function* () {
|
|
21
|
+
const capabilities = yield* Capability.Service;
|
|
22
|
+
|
|
23
|
+
return Capability.contributes(FileCapabilities.Backend, {
|
|
24
|
+
id: WNFS_BACKEND_ID,
|
|
25
|
+
name: 'WNFS',
|
|
26
|
+
description: 'Decentralized, end-to-end encrypted storage via Web Native File System.',
|
|
27
|
+
upload: async (file, db) => {
|
|
28
|
+
const client = capabilities.get(ClientCapabilities.Client);
|
|
29
|
+
const blockstore = capabilities.get(WnfsCapabilities.Blockstore);
|
|
30
|
+
const instances = capabilities.get(WnfsCapabilities.Instances);
|
|
31
|
+
const space = client.spaces.get(db.spaceId);
|
|
32
|
+
invariant(space, 'Space not found');
|
|
33
|
+
const info = await upload({ file, blockstore, instances, space });
|
|
34
|
+
return {
|
|
35
|
+
name: info.name,
|
|
36
|
+
type: info.type,
|
|
37
|
+
size: file.size,
|
|
38
|
+
data: File.externalData(info.url, info.cid),
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
@@ -7,8 +7,9 @@ import * as Effect from 'effect/Effect';
|
|
|
7
7
|
import { Capability } from '@dxos/app-framework';
|
|
8
8
|
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
9
9
|
|
|
10
|
-
import
|
|
11
|
-
|
|
10
|
+
import { WnfsCapabilities } from '#types';
|
|
11
|
+
|
|
12
|
+
import * as Blockstore from '../blockstore';
|
|
12
13
|
|
|
13
14
|
export default Capability.makeModule(
|
|
14
15
|
Effect.fnUntraced(function* () {
|
|
@@ -2,8 +2,17 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
|
|
5
|
+
import { Capability } from '@dxos/app-framework';
|
|
6
|
+
import { type FileCapabilities } from '@dxos/plugin-file/types';
|
|
7
|
+
|
|
8
|
+
export const Backend: Capability.LazyCapability<
|
|
9
|
+
void,
|
|
10
|
+
Capability.Capability<Capability.InterfaceDef<FileCapabilities.Backend>>
|
|
11
|
+
> = Capability.lazy('Backend', () => import('./backend'));
|
|
12
|
+
|
|
13
|
+
export const Blockstore = Capability.lazy('Blockstore', () => import('./blockstore'));
|
|
14
|
+
|
|
15
|
+
export const UrlResolver: Capability.LazyCapability<
|
|
16
|
+
void,
|
|
17
|
+
Capability.Capability<Capability.InterfaceDef<FileCapabilities.UrlResolver>>
|
|
18
|
+
> = Capability.lazy('UrlResolver', () => import('./url-resolver'));
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Capability } from '@dxos/app-framework';
|
|
8
|
+
import { FileCapabilities } from '@dxos/plugin-file/types';
|
|
9
|
+
|
|
10
|
+
import { WnfsCapabilities } from '#types';
|
|
11
|
+
|
|
12
|
+
import { getBlobUrl, loadWnfs } from '../helpers';
|
|
13
|
+
|
|
14
|
+
export const WNFS_URL_RESOLVER_ID = 'wnfs';
|
|
15
|
+
|
|
16
|
+
export default Capability.makeModule(
|
|
17
|
+
Effect.fnUntraced(function* () {
|
|
18
|
+
const capabilities = yield* Capability.Service;
|
|
19
|
+
|
|
20
|
+
return Capability.contributes(FileCapabilities.UrlResolver, {
|
|
21
|
+
id: WNFS_URL_RESOLVER_ID,
|
|
22
|
+
test: (url) => url.startsWith('wnfs://'),
|
|
23
|
+
resolve: async (wnfsUrl, file, space) => {
|
|
24
|
+
if (!space) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const blockstore = capabilities.get(WnfsCapabilities.Blockstore);
|
|
29
|
+
const instances = capabilities.get(WnfsCapabilities.Instances);
|
|
30
|
+
const { directory, forest } = await loadWnfs({ blockstore, instances, space });
|
|
31
|
+
return await getBlobUrl({
|
|
32
|
+
wnfsUrl,
|
|
33
|
+
blockstore,
|
|
34
|
+
directory,
|
|
35
|
+
forest,
|
|
36
|
+
type: file.type,
|
|
37
|
+
});
|
|
38
|
+
} catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}),
|
|
44
|
+
);
|
package/src/helpers/load.ts
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import * as Option from 'effect/Option';
|
|
5
6
|
import type { Blockstore } from 'interface-blockstore';
|
|
6
7
|
import { CID } from 'multiformats';
|
|
7
8
|
import * as Uint8Arrays from 'uint8arrays';
|
|
8
9
|
import { AccessKey, PrivateDirectory, PrivateForest, PrivateNode } from 'wnfs';
|
|
9
10
|
|
|
10
|
-
import { Obj } from '@dxos/echo';
|
|
11
|
+
import { Annotation, Obj } from '@dxos/echo';
|
|
11
12
|
import { type Space } from '@dxos/react-client/echo';
|
|
12
13
|
|
|
13
|
-
import { type WnfsCapabilities } from '
|
|
14
|
+
import { type WnfsCapabilities } from '#types';
|
|
14
15
|
|
|
16
|
+
import { WnfsStateAnnotation } from '../annotations';
|
|
15
17
|
import { Rng, store } from './common';
|
|
16
18
|
|
|
17
19
|
//
|
|
@@ -28,23 +30,37 @@ export const loadWnfs = async ({
|
|
|
28
30
|
instances?: WnfsCapabilities.Instances;
|
|
29
31
|
}) => {
|
|
30
32
|
// TODO(wittjosiah): Remove.
|
|
31
|
-
// Delete old properties if they exist.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
delete
|
|
33
|
+
// Delete old properties if they exist (pre-DX-971 migration cleanup).
|
|
34
|
+
const propsAny = space.properties as any;
|
|
35
|
+
if (propsAny.wnfs_access_key !== undefined && propsAny.wnfs_private_forest_cid !== undefined) {
|
|
36
|
+
Obj.update(space.properties, (obj) => {
|
|
37
|
+
delete (obj as any)['wnfs_access_key'];
|
|
38
|
+
delete (obj as any)['wnfs_private_forest_cid'];
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// Migrate legacy wnfs data key to annotation.
|
|
42
|
+
if (propsAny.wnfs !== undefined && Option.isNone(Annotation.get(space.properties, WnfsStateAnnotation))) {
|
|
43
|
+
Obj.update(space.properties, (properties) => {
|
|
44
|
+
Annotation.set(properties, WnfsStateAnnotation, propsAny.wnfs);
|
|
45
|
+
delete (properties as any)['wnfs'];
|
|
36
46
|
});
|
|
37
47
|
}
|
|
38
48
|
|
|
39
|
-
const
|
|
40
|
-
|
|
49
|
+
const wnfsState = Annotation.get(space.properties, WnfsStateAnnotation).pipe(Option.getOrUndefined);
|
|
50
|
+
const cacheKey = wnfsState?.privateForestCid as any;
|
|
51
|
+
if (cacheKey && instances?.[cacheKey]) {
|
|
41
52
|
return instances[cacheKey];
|
|
42
53
|
}
|
|
43
54
|
|
|
44
|
-
const exists = !!
|
|
55
|
+
const exists = !!wnfsState;
|
|
45
56
|
const instance = exists ? await loadWnfsDir(blockstore, space) : await createWnfsDir(blockstore, space);
|
|
46
57
|
if (instances) {
|
|
47
|
-
instances
|
|
58
|
+
// Re-read after createWnfsDir so newly created instances are cached under the real CID.
|
|
59
|
+
const newCacheKey = Annotation.get(space.properties, WnfsStateAnnotation).pipe(Option.getOrUndefined)
|
|
60
|
+
?.privateForestCid as any;
|
|
61
|
+
if (newCacheKey) {
|
|
62
|
+
instances[newCacheKey] = instance;
|
|
63
|
+
}
|
|
48
64
|
}
|
|
49
65
|
|
|
50
66
|
return instance;
|
|
@@ -68,11 +84,11 @@ const createWnfsDir = async (blockstore: Blockstore, space: Space) => {
|
|
|
68
84
|
|
|
69
85
|
const cidBytes = await newForest.store(wnfsStore);
|
|
70
86
|
|
|
71
|
-
Obj.
|
|
72
|
-
|
|
87
|
+
Obj.update(space.properties, (properties) => {
|
|
88
|
+
Annotation.set(properties, WnfsStateAnnotation, {
|
|
73
89
|
accessKey: Uint8Arrays.toString(accessKeyRaw.toBytes(), 'base64'),
|
|
74
90
|
privateForestCid: CID.decode(cidBytes).toString(),
|
|
75
|
-
};
|
|
91
|
+
});
|
|
76
92
|
});
|
|
77
93
|
|
|
78
94
|
return {
|
|
@@ -84,11 +100,9 @@ const createWnfsDir = async (blockstore: Blockstore, space: Space) => {
|
|
|
84
100
|
const loadWnfsDir = async (blockstore: Blockstore, space: Space) => {
|
|
85
101
|
const wnfsStore = store(blockstore);
|
|
86
102
|
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
wnfsStore,
|
|
91
|
-
);
|
|
103
|
+
const wnfsState = Annotation.get(space.properties, WnfsStateAnnotation).pipe(Option.getOrUndefined)!;
|
|
104
|
+
const accessKey = AccessKey.fromBytes(Uint8Arrays.fromString(wnfsState.accessKey, 'base64'));
|
|
105
|
+
const forest: PrivateForest = await PrivateForest.load(CID.parse(wnfsState.privateForestCid).bytes, wnfsStore);
|
|
92
106
|
const node: PrivateNode = await PrivateNode.load(accessKey, forest, wnfsStore);
|
|
93
107
|
|
|
94
108
|
return {
|
package/src/helpers/upload.ts
CHANGED
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import * as Option from 'effect/Option';
|
|
5
6
|
import type { Blockstore } from 'interface-blockstore';
|
|
6
7
|
import { CID } from 'multiformats';
|
|
7
8
|
import * as Raw from 'multiformats/codecs/raw';
|
|
8
9
|
import { sha256 } from 'multiformats/hashes/sha2';
|
|
9
10
|
|
|
10
11
|
import type { Space } from '@dxos/client/echo';
|
|
11
|
-
import { Obj } from '@dxos/echo';
|
|
12
|
+
import { Annotation, Obj } from '@dxos/echo';
|
|
12
13
|
import { log } from '@dxos/log';
|
|
13
14
|
|
|
14
|
-
import { type WnfsCapabilities } from '
|
|
15
|
+
import { type WnfsCapabilities } from '#types';
|
|
15
16
|
|
|
17
|
+
import { WnfsStateAnnotation } from '../annotations';
|
|
16
18
|
import { Rng, filePath, store } from './common';
|
|
17
19
|
import { loadWnfs } from './load';
|
|
18
20
|
import { wnfsUrl } from './wnfs-url';
|
|
@@ -47,8 +49,15 @@ export const upload = async ({
|
|
|
47
49
|
const cidBytes = await updatedForest.store(wnfsStore);
|
|
48
50
|
|
|
49
51
|
// Update the forest pointer on the associated space.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
const currentState = Annotation.get(space.properties, WnfsStateAnnotation).pipe(Option.getOrUndefined);
|
|
53
|
+
if (!currentState) {
|
|
54
|
+
throw new Error('WnfsStateAnnotation missing after loadWnfs; cannot persist forest CID.');
|
|
55
|
+
}
|
|
56
|
+
Obj.update(space.properties, (properties) => {
|
|
57
|
+
Annotation.set(properties, WnfsStateAnnotation, {
|
|
58
|
+
...currentState,
|
|
59
|
+
privateForestCid: CID.decode(cidBytes).toString(),
|
|
60
|
+
});
|
|
52
61
|
});
|
|
53
62
|
|
|
54
63
|
// Generate `wnfs://` URL & return the info.
|
package/src/index.ts
CHANGED
package/src/meta.ts
CHANGED
|
@@ -2,17 +2,33 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Plugin } from '@dxos/app-framework';
|
|
6
|
+
import { DXN } from '@dxos/keys';
|
|
7
|
+
import { meta as fileMeta } from '@dxos/plugin-file';
|
|
6
8
|
import { trim } from '@dxos/util';
|
|
7
9
|
|
|
8
|
-
export const meta
|
|
9
|
-
|
|
10
|
+
export const meta = Plugin.makeMeta({
|
|
11
|
+
key: DXN.make('org.dxos.plugin.wnfs'),
|
|
10
12
|
name: 'WNFS',
|
|
13
|
+
author: 'DXOS',
|
|
11
14
|
description: trim`
|
|
12
|
-
Decentralized file storage
|
|
13
|
-
|
|
15
|
+
Decentralized, end-to-end encrypted file storage for DXOS Composer built on the Web Native File System (WNFS) protocol.
|
|
16
|
+
|
|
17
|
+
WNFS organizes files inside a cryptographic "dark forest" — a content-addressed private file system
|
|
18
|
+
where each write produces a new immutable root CID. Files are stored as IPLD blocks (CIDv1, sha2-256),
|
|
19
|
+
cached locally in IndexedDB, and asynchronously replicated to the DXOS edge blob service as CAR archives.
|
|
20
|
+
Uploads and reads are scoped to a DXOS Space; the forest root CID is persisted atomically on the
|
|
21
|
+
space's ECHO properties so the file system state survives across sessions and devices.
|
|
22
|
+
|
|
23
|
+
The plugin registers as a \`FileCapabilities.Backend\` and \`FileCapabilities.UrlResolver\` so any plugin
|
|
24
|
+
that uses \`plugin-file\` (e.g. \`plugin-gallery\`) can upload files and resolve \`wnfs://\` URLs without
|
|
25
|
+
coupling to the storage implementation. The blockstore automatically queues blocks while offline and
|
|
26
|
+
flushes them when connectivity is restored.
|
|
14
27
|
`,
|
|
15
28
|
icon: 'ph--file-cloud--regular',
|
|
16
29
|
iconHue: 'teal',
|
|
17
30
|
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-wnfs',
|
|
18
|
-
|
|
31
|
+
spec: 'PLUGIN.mdl',
|
|
32
|
+
tags: ['labs'],
|
|
33
|
+
dependsOn: [fileMeta.id],
|
|
34
|
+
});
|