@dxos/plugin-wnfs 0.8.4-main.fcfe5033a5 → 0.8.4-staging.60fe92afc8
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/neutral/blockstore-U6SPNL2C.mjs +190 -0
- 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-N6Y4QPNF.mjs → neutral/chunk-L33MOD23.mjs} +97 -28
- 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 -1
- package/dist/types/src/capabilities/index.d.ts +3 -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.map +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 -16
- 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 +74 -61
- package/src/WnfsPlugin.node.ts +11 -0
- package/src/WnfsPlugin.test.ts +20 -0
- package/src/WnfsPlugin.tsx +16 -40
- package/src/WnfsPlugin.workerd.ts +11 -0
- package/src/annotations.ts +16 -0
- package/src/capabilities/backend.ts +43 -0
- package/src/capabilities/blockstore.ts +1 -1
- package/src/capabilities/index.ts +11 -8
- package/src/capabilities/url-resolver.ts +44 -0
- package/src/helpers/load.ts +32 -18
- package/src/helpers/upload.ts +12 -3
- package/src/index.ts +3 -2
- package/src/meta.ts +22 -6
- package/src/plugin.ts +9 -0
- package/src/translations.ts +1 -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/chunk-BM3MEFES.mjs +0 -69
- package/dist/lib/browser/chunk-BM3MEFES.mjs.map +0 -7
- package/dist/lib/browser/chunk-N6Y4QPNF.mjs.map +0 -7
- package/dist/lib/browser/chunk-VXUCZHVZ.mjs +0 -69
- package/dist/lib/browser/chunk-VXUCZHVZ.mjs.map +0 -7
- package/dist/lib/browser/create-NOHKWE67.mjs +0 -24
- package/dist/lib/browser/create-NOHKWE67.mjs.map +0 -7
- package/dist/lib/browser/create-file-N7ADCFOF.mjs +0 -49
- package/dist/lib/browser/create-file-N7ADCFOF.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/meta.json +0 -1
- package/dist/lib/browser/operations/index.mjs +0 -13
- package/dist/lib/browser/operations/index.mjs.map +0 -7
- package/dist/lib/browser/types/index.mjs +0 -11
- package/dist/lib/browser/upload-DA7GBOXF.mjs +0 -42
- package/dist/lib/browser/upload-DA7GBOXF.mjs.map +0 -7
- package/dist/types/src/capabilities/file-uploader.d.ts +0 -6
- package/dist/types/src/capabilities/file-uploader.d.ts.map +0 -1
- package/dist/types/src/capabilities/markdown.d.ts +0 -5
- package/dist/types/src/capabilities/markdown.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-handler.d.ts +0 -6
- package/dist/types/src/capabilities/operation-handler.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface.d.ts +0 -5
- package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
- package/dist/types/src/components/FileInput/FileInput.d.ts +0 -8
- package/dist/types/src/components/FileInput/FileInput.d.ts.map +0 -1
- package/dist/types/src/components/FileInput/index.d.ts +0 -2
- package/dist/types/src/components/FileInput/index.d.ts.map +0 -1
- package/dist/types/src/components/FilePreview/FilePreview.d.ts +0 -12
- package/dist/types/src/components/FilePreview/FilePreview.d.ts.map +0 -1
- package/dist/types/src/components/FilePreview/index.d.ts +0 -2
- package/dist/types/src/components/FilePreview/index.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 -2
- 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/operations/create-file.d.ts +0 -5
- package/dist/types/src/operations/create-file.d.ts.map +0 -1
- package/dist/types/src/operations/create.d.ts +0 -5
- package/dist/types/src/operations/create.d.ts.map +0 -1
- package/dist/types/src/operations/definitions.d.ts +0 -38
- package/dist/types/src/operations/definitions.d.ts.map +0 -1
- package/dist/types/src/operations/index.d.ts +0 -4
- package/dist/types/src/operations/index.d.ts.map +0 -1
- package/dist/types/src/operations/upload.d.ts +0 -5
- package/dist/types/src/operations/upload.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 -9
- package/dist/types/src/types/types.d.ts.map +0 -1
- package/src/capabilities/file-uploader.ts +0 -34
- package/src/capabilities/markdown.ts +0 -34
- package/src/capabilities/operation-handler.ts +0 -16
- package/src/capabilities/react-surface.tsx +0 -54
- package/src/components/FileInput/FileInput.tsx +0 -47
- package/src/components/FileInput/index.ts +0 -5
- package/src/components/FilePreview/FilePreview.tsx +0 -43
- package/src/components/FilePreview/index.ts +0 -5
- package/src/components/index.ts +0 -6
- package/src/containers/FileContainer/FileContainer.tsx +0 -57
- package/src/containers/FileContainer/index.ts +0 -5
- package/src/containers/index.ts +0 -7
- package/src/extensions/image.stories.tsx +0 -103
- package/src/extensions/image.tsx +0 -204
- package/src/extensions/index.ts +0 -5
- package/src/operations/create-file.ts +0 -31
- package/src/operations/create.ts +0 -22
- package/src/operations/definitions.ts +0 -41
- package/src/operations/index.ts +0 -13
- package/src/operations/upload.ts +0 -29
- package/src/types/File.ts +0 -28
- package/src/types/capabilities.ts +0 -18
- package/src/types/types.ts +0 -24
- /package/dist/lib/{browser/types/index.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-wnfs",
|
|
3
|
-
"version": "0.8.4-
|
|
3
|
+
"version": "0.8.4-staging.60fe92afc8",
|
|
4
4
|
"description": "WNFS file management plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -8,102 +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",
|
|
14
15
|
"imports": {
|
|
15
|
-
"#capabilities":
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"#
|
|
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
|
+
}
|
|
21
52
|
},
|
|
22
53
|
"exports": {
|
|
23
54
|
".": {
|
|
24
55
|
"source": "./src/index.ts",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
56
|
+
"types": "./dist/types/src/index.d.ts",
|
|
57
|
+
"default": "./dist/lib/neutral/index.mjs"
|
|
27
58
|
},
|
|
28
|
-
"./
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"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"
|
|
32
64
|
},
|
|
33
|
-
"./
|
|
34
|
-
"source": "./src/
|
|
35
|
-
"
|
|
36
|
-
"
|
|
65
|
+
"./translations": {
|
|
66
|
+
"source": "./src/translations.ts",
|
|
67
|
+
"types": "./dist/types/src/translations.d.ts",
|
|
68
|
+
"default": "./dist/lib/neutral/translations.mjs"
|
|
37
69
|
}
|
|
38
70
|
},
|
|
39
71
|
"types": "dist/types/src/index.d.ts",
|
|
40
|
-
"typesVersions": {
|
|
41
|
-
"*": {
|
|
42
|
-
"types": [
|
|
43
|
-
"dist/types/src/types/index.d.ts"
|
|
44
|
-
],
|
|
45
|
-
"operations": [
|
|
46
|
-
"dist/types/src/operations/index.d.ts"
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
72
|
"files": [
|
|
51
73
|
"dist",
|
|
52
|
-
"src"
|
|
74
|
+
"src",
|
|
75
|
+
"PLUGIN.mdl"
|
|
53
76
|
],
|
|
54
77
|
"dependencies": {
|
|
55
|
-
"@codemirror/language": "^6.11.3",
|
|
56
|
-
"@codemirror/state": "^6.5.2",
|
|
57
|
-
"@codemirror/view": "^6.38.4",
|
|
58
78
|
"@ipld/car": "^5.3.3",
|
|
59
79
|
"blockstore-core": "^5.0.1",
|
|
60
80
|
"blockstore-idb": "^2.0.0",
|
|
61
81
|
"debounce": "^2.2.0",
|
|
62
|
-
"effect": "3.
|
|
82
|
+
"effect": "3.21.3",
|
|
63
83
|
"idb-keyval": "^6.2.1",
|
|
64
84
|
"interface-blockstore": "^5.2.10",
|
|
65
85
|
"it-all": "^3.0.6",
|
|
66
86
|
"multiformats": "^13.2.2",
|
|
67
|
-
"react-dropzone": "^14.2.3",
|
|
68
87
|
"uint8arrays": "^5.1.0",
|
|
69
88
|
"wnfs": "0.2.2",
|
|
70
|
-
"@dxos/app-framework": "0.8.4-
|
|
71
|
-
"@dxos/app-toolkit": "0.8.4-
|
|
72
|
-
"@dxos/crypto": "0.8.4-
|
|
73
|
-
"@dxos/echo": "0.8.4-
|
|
74
|
-
"@dxos/
|
|
75
|
-
"@dxos/
|
|
76
|
-
"@dxos/
|
|
77
|
-
"@dxos/
|
|
78
|
-
"@dxos/plugin-
|
|
79
|
-
"@dxos/react-client": "0.8.4-
|
|
80
|
-
"@dxos/react-ui": "0.8.4-
|
|
81
|
-
"@dxos/
|
|
82
|
-
"@dxos/
|
|
83
|
-
"@dxos/react-ui-form": "0.8.4-main.fcfe5033a5",
|
|
84
|
-
"@dxos/react-ui-mosaic": "0.8.4-main.fcfe5033a5",
|
|
85
|
-
"@dxos/react-ui-stack": "0.8.4-main.fcfe5033a5",
|
|
86
|
-
"@dxos/ui-editor": "0.8.4-main.fcfe5033a5",
|
|
87
|
-
"@dxos/schema": "0.8.4-main.fcfe5033a5",
|
|
88
|
-
"@dxos/plugin-client": "0.8.4-main.fcfe5033a5",
|
|
89
|
-
"@dxos/util": "0.8.4-main.fcfe5033a5"
|
|
89
|
+
"@dxos/app-framework": "0.8.4-staging.60fe92afc8",
|
|
90
|
+
"@dxos/app-toolkit": "0.8.4-staging.60fe92afc8",
|
|
91
|
+
"@dxos/crypto": "0.8.4-staging.60fe92afc8",
|
|
92
|
+
"@dxos/echo": "0.8.4-staging.60fe92afc8",
|
|
93
|
+
"@dxos/invariant": "0.8.4-staging.60fe92afc8",
|
|
94
|
+
"@dxos/log": "0.8.4-staging.60fe92afc8",
|
|
95
|
+
"@dxos/plugin-client": "0.8.4-staging.60fe92afc8",
|
|
96
|
+
"@dxos/keys": "0.8.4-staging.60fe92afc8",
|
|
97
|
+
"@dxos/plugin-file": "0.8.4-staging.60fe92afc8",
|
|
98
|
+
"@dxos/react-client": "0.8.4-staging.60fe92afc8",
|
|
99
|
+
"@dxos/react-ui": "0.8.4-staging.60fe92afc8",
|
|
100
|
+
"@dxos/util": "0.8.4-staging.60fe92afc8",
|
|
101
|
+
"@dxos/types": "0.8.4-staging.60fe92afc8"
|
|
90
102
|
},
|
|
91
103
|
"devDependencies": {
|
|
92
104
|
"@types/react": "~19.2.7",
|
|
93
105
|
"@types/react-dom": "~19.2.3",
|
|
94
106
|
"react": "~19.2.3",
|
|
95
107
|
"react-dom": "~19.2.3",
|
|
96
|
-
"vite": "^
|
|
97
|
-
"@dxos/random": "0.8.4-
|
|
98
|
-
"@dxos/
|
|
99
|
-
"@dxos/
|
|
108
|
+
"vite": "^8.0.16",
|
|
109
|
+
"@dxos/random": "0.8.4-staging.60fe92afc8",
|
|
110
|
+
"@dxos/ui-theme": "0.8.4-staging.60fe92afc8",
|
|
111
|
+
"@dxos/storybook-utils": "0.8.4-staging.60fe92afc8",
|
|
112
|
+
"@dxos/plugin-testing": "0.8.4-staging.60fe92afc8"
|
|
100
113
|
},
|
|
101
114
|
"peerDependencies": {
|
|
102
|
-
"effect": "3.
|
|
115
|
+
"effect": "3.21.3",
|
|
103
116
|
"react": "~19.2.3",
|
|
104
117
|
"react-dom": "~19.2.3",
|
|
105
|
-
"@dxos/react-ui": "0.8.4-
|
|
106
|
-
"@dxos/ui-theme": "0.8.4-
|
|
118
|
+
"@dxos/react-ui": "0.8.4-staging.60fe92afc8",
|
|
119
|
+
"@dxos/ui-theme": "0.8.4-staging.60fe92afc8"
|
|
107
120
|
},
|
|
108
121
|
"publishConfig": {
|
|
109
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
|
@@ -3,49 +3,20 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
|
-
import * as Option from 'effect/Option';
|
|
7
6
|
|
|
8
7
|
import { Capability, Plugin } from '@dxos/app-framework';
|
|
9
8
|
import { AppPlugin } from '@dxos/app-toolkit';
|
|
10
|
-
import {
|
|
11
|
-
import { Operation } from '@dxos/operation';
|
|
12
|
-
import { ClientEvents } from '@dxos/plugin-client/types';
|
|
13
|
-
import { MarkdownEvents } from '@dxos/plugin-markdown';
|
|
14
|
-
import { SpaceOperation } from '@dxos/plugin-space/operations';
|
|
15
|
-
import { type CreateObject } from '@dxos/plugin-space/types';
|
|
9
|
+
import { ClientEvents } from '@dxos/plugin-client';
|
|
16
10
|
|
|
17
|
-
import {
|
|
11
|
+
import { Backend, Blockstore, UrlResolver } from '#capabilities';
|
|
18
12
|
import { meta } from '#meta';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
13
|
+
import { translations } from '#translations';
|
|
14
|
+
import { WnfsCapabilities } from '#types';
|
|
21
15
|
|
|
22
|
-
|
|
16
|
+
// eslint-disable-next-line import/no-relative-packages
|
|
17
|
+
import pluginSpec from '../PLUGIN.mdl?raw';
|
|
23
18
|
|
|
24
19
|
export const WnfsPlugin = Plugin.define(meta).pipe(
|
|
25
|
-
AppPlugin.addMetadataModule({
|
|
26
|
-
metadata: {
|
|
27
|
-
id: WnfsFile.File.typename,
|
|
28
|
-
metadata: {
|
|
29
|
-
// TODO(wittjosiah): Would be nice if icon could change based on the type of the file.
|
|
30
|
-
icon: Annotation.IconAnnotation.get(WnfsFile.File).pipe(Option.getOrThrow).icon,
|
|
31
|
-
iconHue: Annotation.IconAnnotation.get(WnfsFile.File).pipe(Option.getOrThrow).hue ?? 'white',
|
|
32
|
-
inputSchema: WnfsAction.UploadFileSchema,
|
|
33
|
-
createObject: ((props, options) =>
|
|
34
|
-
Effect.gen(function* () {
|
|
35
|
-
const { object } = yield* Operation.invoke(WnfsOperation.CreateFile, { ...props, db: options.db });
|
|
36
|
-
return yield* Operation.invoke(SpaceOperation.AddObject, {
|
|
37
|
-
object,
|
|
38
|
-
target: options.target,
|
|
39
|
-
hidden: true,
|
|
40
|
-
targetNodeId: options.targetNodeId,
|
|
41
|
-
});
|
|
42
|
-
})) satisfies CreateObject,
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
}),
|
|
46
|
-
AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
|
|
47
|
-
AppPlugin.addSchemaModule({ schema: [WnfsFile.File] }),
|
|
48
|
-
AppPlugin.addSurfaceModule({ activate: ReactSurface }),
|
|
49
20
|
AppPlugin.addTranslationsModule({ translations }),
|
|
50
21
|
Plugin.addModule({
|
|
51
22
|
id: 'blockstore',
|
|
@@ -62,14 +33,19 @@ export const WnfsPlugin = Plugin.define(meta).pipe(
|
|
|
62
33
|
}),
|
|
63
34
|
}),
|
|
64
35
|
Plugin.addModule({
|
|
65
|
-
id: '
|
|
36
|
+
id: 'backend',
|
|
66
37
|
activatesOn: ClientEvents.ClientReady,
|
|
67
|
-
activate:
|
|
38
|
+
activate: Backend,
|
|
68
39
|
}),
|
|
69
40
|
Plugin.addModule({
|
|
70
|
-
id: '
|
|
71
|
-
activatesOn:
|
|
72
|
-
activate:
|
|
41
|
+
id: 'url-resolver',
|
|
42
|
+
activatesOn: ClientEvents.ClientReady,
|
|
43
|
+
activate: UrlResolver,
|
|
44
|
+
}),
|
|
45
|
+
AppPlugin.addPluginAssetModule({
|
|
46
|
+
asset: { pluginId: meta.id, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
|
|
73
47
|
}),
|
|
74
48
|
Plugin.make,
|
|
75
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
|
+
});
|
|
@@ -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
|
+
);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import * as Effect from 'effect/Effect';
|
|
6
6
|
|
|
7
7
|
import { Capability } from '@dxos/app-framework';
|
|
8
|
-
import { ClientCapabilities } from '@dxos/plugin-client
|
|
8
|
+
import { ClientCapabilities } from '@dxos/plugin-client';
|
|
9
9
|
|
|
10
10
|
import { WnfsCapabilities } from '#types';
|
|
11
11
|
|
|
@@ -3,13 +3,16 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Capability } from '@dxos/app-framework';
|
|
6
|
-
import {
|
|
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'));
|
|
7
12
|
|
|
8
13
|
export const Blockstore = Capability.lazy('Blockstore', () => import('./blockstore'));
|
|
9
|
-
|
|
10
|
-
export const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
);
|
|
15
|
-
export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
|
|
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
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 obj['
|
|
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
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
|
+
});
|