@dxos/plugin-wnfs 0.8.4-main.7ace549 → 0.8.4-main.8baae0fced

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 (156) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +2 -2
  3. package/dist/lib/neutral/WnfsPlugin.mjs +39 -0
  4. package/dist/lib/neutral/WnfsPlugin.mjs.map +7 -0
  5. package/dist/lib/neutral/WnfsPlugin.node.mjs +12 -0
  6. package/dist/lib/neutral/WnfsPlugin.node.mjs.map +7 -0
  7. package/dist/lib/neutral/WnfsPlugin.workerd.mjs +12 -0
  8. package/dist/lib/neutral/WnfsPlugin.workerd.mjs.map +7 -0
  9. package/dist/lib/neutral/backend-DHBQUTPC.mjs +47 -0
  10. package/dist/lib/neutral/backend-DHBQUTPC.mjs.map +7 -0
  11. package/dist/lib/{browser/blockstore-2JFU4NBU.mjs → neutral/blockstore-3NLSWC7Z.mjs} +12 -13
  12. package/dist/lib/neutral/blockstore-3NLSWC7Z.mjs.map +7 -0
  13. package/dist/lib/neutral/capabilities/index.mjs +13 -0
  14. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  15. package/dist/lib/{browser/chunk-D6VTEQIE.mjs → neutral/chunk-7KFJ6LYH.mjs} +43 -18
  16. package/dist/lib/neutral/chunk-7KFJ6LYH.mjs.map +7 -0
  17. package/dist/lib/{browser/chunk-OGPGLJCV.mjs → neutral/chunk-EKFVDDRY.mjs} +11 -10
  18. package/dist/lib/neutral/chunk-EKFVDDRY.mjs.map +7 -0
  19. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  20. package/dist/lib/neutral/chunk-QODCKFTY.mjs +19 -0
  21. package/dist/lib/neutral/chunk-QODCKFTY.mjs.map +7 -0
  22. package/dist/lib/neutral/helpers/index.mjs +26 -0
  23. package/dist/lib/neutral/helpers/index.mjs.map +7 -0
  24. package/dist/lib/neutral/index.mjs +34 -0
  25. package/dist/lib/neutral/index.mjs.map +7 -0
  26. package/dist/lib/neutral/meta.json +1 -0
  27. package/dist/lib/neutral/meta.mjs +8 -0
  28. package/dist/lib/neutral/meta.mjs.map +7 -0
  29. package/dist/lib/neutral/plugin.mjs +12 -0
  30. package/dist/lib/neutral/plugin.mjs.map +7 -0
  31. package/dist/lib/neutral/translations.mjs +17 -0
  32. package/dist/lib/neutral/translations.mjs.map +7 -0
  33. package/dist/lib/neutral/types/index.mjs +8 -0
  34. package/dist/lib/neutral/types/index.mjs.map +7 -0
  35. package/dist/lib/neutral/url-resolver-UD3ZP77Y.mjs +47 -0
  36. package/dist/lib/neutral/url-resolver-UD3ZP77Y.mjs.map +7 -0
  37. package/dist/types/src/WnfsPlugin.d.ts +3 -1
  38. package/dist/types/src/WnfsPlugin.d.ts.map +1 -1
  39. package/dist/types/src/WnfsPlugin.node.d.ts +4 -0
  40. package/dist/types/src/WnfsPlugin.node.d.ts.map +1 -0
  41. package/dist/types/src/WnfsPlugin.test.d.ts +2 -0
  42. package/dist/types/src/WnfsPlugin.test.d.ts.map +1 -0
  43. package/dist/types/src/WnfsPlugin.workerd.d.ts +4 -0
  44. package/dist/types/src/WnfsPlugin.workerd.d.ts.map +1 -0
  45. package/dist/types/src/blockstore.d.ts.map +1 -1
  46. package/dist/types/src/capabilities/backend.d.ts +7 -0
  47. package/dist/types/src/capabilities/backend.d.ts.map +1 -0
  48. package/dist/types/src/capabilities/blockstore.d.ts +3 -2
  49. package/dist/types/src/capabilities/blockstore.d.ts.map +1 -1
  50. package/dist/types/src/capabilities/index.d.ts +5 -6
  51. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  52. package/dist/types/src/capabilities/url-resolver.d.ts +7 -0
  53. package/dist/types/src/capabilities/url-resolver.d.ts.map +1 -0
  54. package/dist/types/src/helpers/common.d.ts.map +1 -1
  55. package/dist/types/src/helpers/load.d.ts +1 -1
  56. package/dist/types/src/helpers/load.d.ts.map +1 -1
  57. package/dist/types/src/helpers/upload.d.ts +1 -1
  58. package/dist/types/src/helpers/upload.d.ts.map +1 -1
  59. package/dist/types/src/helpers/wnfs-url.d.ts.map +1 -1
  60. package/dist/types/src/index.d.ts +2 -2
  61. package/dist/types/src/index.d.ts.map +1 -1
  62. package/dist/types/src/meta.d.ts +2 -2
  63. package/dist/types/src/meta.d.ts.map +1 -1
  64. package/dist/types/src/plugin.d.ts +3 -0
  65. package/dist/types/src/plugin.d.ts.map +1 -0
  66. package/dist/types/src/translations.d.ts +2 -12
  67. package/dist/types/src/translations.d.ts.map +1 -1
  68. package/dist/types/src/types/WnfsCapabilities.d.ts +11 -0
  69. package/dist/types/src/types/WnfsCapabilities.d.ts.map +1 -0
  70. package/dist/types/src/types/index.d.ts +1 -2
  71. package/dist/types/src/types/index.d.ts.map +1 -1
  72. package/dist/types/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +108 -46
  74. package/src/WnfsPlugin.node.ts +11 -0
  75. package/src/WnfsPlugin.test.ts +20 -0
  76. package/src/WnfsPlugin.tsx +28 -72
  77. package/src/WnfsPlugin.workerd.ts +11 -0
  78. package/src/blockstore.ts +1 -1
  79. package/src/capabilities/backend.ts +43 -0
  80. package/src/capabilities/blockstore.ts +14 -10
  81. package/src/capabilities/index.ts +12 -7
  82. package/src/capabilities/url-resolver.ts +44 -0
  83. package/src/helpers/load.ts +12 -7
  84. package/src/helpers/upload.ts +5 -2
  85. package/src/index.ts +2 -2
  86. package/src/meta.ts +7 -3
  87. package/src/plugin.ts +9 -0
  88. package/src/translations.ts +2 -11
  89. package/src/types/WnfsCapabilities.ts +18 -0
  90. package/src/types/index.ts +1 -2
  91. package/dist/lib/browser/FileContainer-6JIJX7SN.mjs +0 -103
  92. package/dist/lib/browser/FileContainer-6JIJX7SN.mjs.map +0 -7
  93. package/dist/lib/browser/blockstore-2JFU4NBU.mjs.map +0 -7
  94. package/dist/lib/browser/chunk-234GILVK.mjs +0 -71
  95. package/dist/lib/browser/chunk-234GILVK.mjs.map +0 -7
  96. package/dist/lib/browser/chunk-D6VTEQIE.mjs.map +0 -7
  97. package/dist/lib/browser/chunk-F4QHZWQD.mjs +0 -16
  98. package/dist/lib/browser/chunk-F4QHZWQD.mjs.map +0 -7
  99. package/dist/lib/browser/chunk-IVUX2QXX.mjs +0 -16
  100. package/dist/lib/browser/chunk-IVUX2QXX.mjs.map +0 -7
  101. package/dist/lib/browser/chunk-OGPGLJCV.mjs.map +0 -7
  102. package/dist/lib/browser/file-uploader-APZNBT66.mjs +0 -30
  103. package/dist/lib/browser/file-uploader-APZNBT66.mjs.map +0 -7
  104. package/dist/lib/browser/index.mjs +0 -115
  105. package/dist/lib/browser/index.mjs.map +0 -7
  106. package/dist/lib/browser/intent-resolver-246R4ETC.mjs +0 -48
  107. package/dist/lib/browser/intent-resolver-246R4ETC.mjs.map +0 -7
  108. package/dist/lib/browser/markdown-WYQDCVFQ.mjs +0 -198
  109. package/dist/lib/browser/markdown-WYQDCVFQ.mjs.map +0 -7
  110. package/dist/lib/browser/meta.json +0 -1
  111. package/dist/lib/browser/react-surface-CGF34KPI.mjs +0 -88
  112. package/dist/lib/browser/react-surface-CGF34KPI.mjs.map +0 -7
  113. package/dist/lib/browser/types/index.mjs +0 -10
  114. package/dist/types/src/capabilities/capabilities.d.ts +0 -12
  115. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  116. package/dist/types/src/capabilities/file-uploader.d.ts +0 -4
  117. package/dist/types/src/capabilities/file-uploader.d.ts.map +0 -1
  118. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  119. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  120. package/dist/types/src/capabilities/markdown.d.ts +0 -4
  121. package/dist/types/src/capabilities/markdown.d.ts.map +0 -1
  122. package/dist/types/src/capabilities/react-surface.d.ts +0 -4
  123. package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
  124. package/dist/types/src/components/FileContainer.d.ts +0 -9
  125. package/dist/types/src/components/FileContainer.d.ts.map +0 -1
  126. package/dist/types/src/components/FileInput.d.ts +0 -8
  127. package/dist/types/src/components/FileInput.d.ts.map +0 -1
  128. package/dist/types/src/components/FilePreview.d.ts +0 -11
  129. package/dist/types/src/components/FilePreview.d.ts.map +0 -1
  130. package/dist/types/src/components/index.d.ts +0 -3
  131. package/dist/types/src/components/index.d.ts.map +0 -1
  132. package/dist/types/src/extensions/image.d.ts +0 -14
  133. package/dist/types/src/extensions/image.d.ts.map +0 -1
  134. package/dist/types/src/extensions/image.stories.d.ts +0 -11
  135. package/dist/types/src/extensions/image.stories.d.ts.map +0 -1
  136. package/dist/types/src/extensions/index.d.ts +0 -2
  137. package/dist/types/src/extensions/index.d.ts.map +0 -1
  138. package/dist/types/src/types/File.d.ts +0 -16
  139. package/dist/types/src/types/File.d.ts.map +0 -1
  140. package/dist/types/src/types/types.d.ts +0 -55
  141. package/dist/types/src/types/types.d.ts.map +0 -1
  142. package/src/capabilities/capabilities.ts +0 -18
  143. package/src/capabilities/file-uploader.ts +0 -27
  144. package/src/capabilities/intent-resolver.ts +0 -32
  145. package/src/capabilities/markdown.ts +0 -26
  146. package/src/capabilities/react-surface.tsx +0 -45
  147. package/src/components/FileContainer.tsx +0 -59
  148. package/src/components/FileInput.tsx +0 -47
  149. package/src/components/FilePreview.tsx +0 -23
  150. package/src/components/index.ts +0 -9
  151. package/src/extensions/image.stories.tsx +0 -104
  152. package/src/extensions/image.tsx +0 -203
  153. package/src/extensions/index.ts +0 -5
  154. package/src/types/File.ts +0 -24
  155. package/src/types/types.ts +0 -41
  156. /package/dist/lib/{browser/types/index.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,32 +1,88 @@
1
1
  {
2
2
  "name": "@dxos/plugin-wnfs",
3
- "version": "0.8.4-main.7ace549",
3
+ "version": "0.8.4-main.8baae0fced",
4
4
  "description": "WNFS file management plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
- "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "FSL-1.1-Apache-2.0",
8
12
  "author": "DXOS.org",
13
+ "sideEffects": true,
9
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
+ "#components": {
22
+ "source": "./src/components/index.ts",
23
+ "types": "./dist/types/src/components/index.d.ts",
24
+ "default": "./dist/lib/neutral/components/index.mjs"
25
+ },
26
+ "#containers": {
27
+ "source": "./src/containers/index.ts",
28
+ "types": "./dist/types/src/containers/index.d.ts",
29
+ "default": "./dist/lib/neutral/containers/index.mjs"
30
+ },
31
+ "#helpers": {
32
+ "source": "./src/helpers/index.ts",
33
+ "types": "./dist/types/src/helpers/index.d.ts",
34
+ "default": "./dist/lib/neutral/helpers/index.mjs"
35
+ },
36
+ "#meta": {
37
+ "source": "./src/meta.ts",
38
+ "types": "./dist/types/src/meta.d.ts",
39
+ "default": "./dist/lib/neutral/meta.mjs"
40
+ },
41
+ "#operations": {
42
+ "source": "./src/operations/index.ts",
43
+ "types": "./dist/types/src/operations/index.d.ts",
44
+ "default": "./dist/lib/neutral/operations/index.mjs"
45
+ },
46
+ "#plugin": {
47
+ "source": {
48
+ "workerd": "./src/WnfsPlugin.workerd.ts",
49
+ "node": "./src/WnfsPlugin.node.ts",
50
+ "default": "./src/WnfsPlugin.tsx"
51
+ },
52
+ "types": "./dist/types/src/WnfsPlugin.d.ts",
53
+ "workerd": "./dist/lib/neutral/WnfsPlugin.workerd.mjs",
54
+ "node": "./dist/lib/neutral/WnfsPlugin.node.mjs",
55
+ "default": "./dist/lib/neutral/WnfsPlugin.mjs"
56
+ },
57
+ "#translations": {
58
+ "source": "./src/translations.ts",
59
+ "types": "./dist/types/src/translations.d.ts",
60
+ "default": "./dist/lib/neutral/translations.mjs"
61
+ },
62
+ "#types": {
63
+ "source": "./src/types/index.ts",
64
+ "types": "./dist/types/src/types/index.d.ts",
65
+ "default": "./dist/lib/neutral/types/index.mjs"
66
+ }
67
+ },
10
68
  "exports": {
11
69
  ".": {
12
70
  "source": "./src/index.ts",
13
71
  "types": "./dist/types/src/index.d.ts",
14
- "browser": "./dist/lib/browser/index.mjs"
72
+ "default": "./dist/lib/neutral/index.mjs"
15
73
  },
16
- "./types": {
17
- "source": "./src/types/index.ts",
18
- "types": "./dist/types/src/types/index.d.ts",
19
- "browser": "./dist/lib/browser/types/index.mjs"
74
+ "./plugin": {
75
+ "source": "./src/plugin.ts",
76
+ "types": "./dist/types/src/plugin.d.ts",
77
+ "default": "./dist/lib/neutral/plugin.mjs"
78
+ },
79
+ "./translations": {
80
+ "source": "./src/translations.ts",
81
+ "types": "./dist/types/src/translations.d.ts",
82
+ "default": "./dist/lib/neutral/translations.mjs"
20
83
  }
21
84
  },
22
85
  "types": "dist/types/src/index.d.ts",
23
- "typesVersions": {
24
- "*": {
25
- "types": [
26
- "dist/types/src/types/index.d.ts"
27
- ]
28
- }
29
- },
30
86
  "files": [
31
87
  "dist",
32
88
  "src"
@@ -34,13 +90,12 @@
34
90
  "dependencies": {
35
91
  "@codemirror/language": "^6.11.3",
36
92
  "@codemirror/state": "^6.5.2",
37
- "@codemirror/view": "^6.38.4",
93
+ "@codemirror/view": "^6.38.5",
38
94
  "@ipld/car": "^5.3.3",
39
- "@preact-signals/safe-react": "^0.9.0",
40
95
  "blockstore-core": "^5.0.1",
41
96
  "blockstore-idb": "^2.0.0",
42
97
  "debounce": "^2.2.0",
43
- "effect": "3.18.3",
98
+ "effect": "3.20.0",
44
99
  "idb-keyval": "^6.2.1",
45
100
  "interface-blockstore": "^5.2.10",
46
101
  "it-all": "^3.0.6",
@@ -48,39 +103,46 @@
48
103
  "react-dropzone": "^14.2.3",
49
104
  "uint8arrays": "^5.1.0",
50
105
  "wnfs": "0.2.2",
51
- "@dxos/app-framework": "0.8.4-main.7ace549",
52
- "@dxos/crypto": "0.8.4-main.7ace549",
53
- "@dxos/echo": "0.8.4-main.7ace549",
54
- "@dxos/effect": "0.8.4-main.7ace549",
55
- "@dxos/invariant": "0.8.4-main.7ace549",
56
- "@dxos/local-storage": "0.8.4-main.7ace549",
57
- "@dxos/log": "0.8.4-main.7ace549",
58
- "@dxos/plugin-client": "0.8.4-main.7ace549",
59
- "@dxos/plugin-space": "0.8.4-main.7ace549",
60
- "@dxos/plugin-markdown": "0.8.4-main.7ace549",
61
- "@dxos/react-client": "0.8.4-main.7ace549",
62
- "@dxos/react-ui-editor": "0.8.4-main.7ace549",
63
- "@dxos/react-ui-form": "0.8.4-main.7ace549",
64
- "@dxos/util": "0.8.4-main.7ace549",
65
- "@dxos/react-ui": "0.8.4-main.7ace549",
66
- "@dxos/react-ui-stack": "0.8.4-main.7ace549"
106
+ "@dxos/app-framework": "0.8.4-main.8baae0fced",
107
+ "@dxos/compute": "0.8.4-main.8baae0fced",
108
+ "@dxos/app-toolkit": "0.8.4-main.8baae0fced",
109
+ "@dxos/effect": "0.8.4-main.8baae0fced",
110
+ "@dxos/echo": "0.8.4-main.8baae0fced",
111
+ "@dxos/invariant": "0.8.4-main.8baae0fced",
112
+ "@dxos/keys": "0.8.4-main.8baae0fced",
113
+ "@dxos/log": "0.8.4-main.8baae0fced",
114
+ "@dxos/plugin-client": "0.8.4-main.8baae0fced",
115
+ "@dxos/plugin-file": "0.8.4-main.8baae0fced",
116
+ "@dxos/plugin-space": "0.8.4-main.8baae0fced",
117
+ "@dxos/react-client": "0.8.4-main.8baae0fced",
118
+ "@dxos/crypto": "0.8.4-main.8baae0fced",
119
+ "@dxos/react-ui": "0.8.4-main.8baae0fced",
120
+ "@dxos/react-ui-editor": "0.8.4-main.8baae0fced",
121
+ "@dxos/react-ui-mosaic": "0.8.4-main.8baae0fced",
122
+ "@dxos/react-ui-stack": "0.8.4-main.8baae0fced",
123
+ "@dxos/types": "0.8.4-main.8baae0fced",
124
+ "@dxos/schema": "0.8.4-main.8baae0fced",
125
+ "@dxos/react-ui-form": "0.8.4-main.8baae0fced",
126
+ "@dxos/util": "0.8.4-main.8baae0fced",
127
+ "@dxos/ui-editor": "0.8.4-main.8baae0fced"
67
128
  },
68
129
  "devDependencies": {
69
- "@types/react": "~19.2.2",
70
- "@types/react-dom": "~19.2.2",
71
- "react": "~19.2.0",
72
- "react-dom": "~19.2.0",
73
- "vite": "7.1.9",
74
- "@dxos/random": "0.8.4-main.7ace549",
75
- "@dxos/storybook-utils": "0.8.4-main.7ace549",
76
- "@dxos/react-ui-theme": "0.8.4-main.7ace549"
130
+ "@types/react": "~19.2.7",
131
+ "@types/react-dom": "~19.2.3",
132
+ "react": "~19.2.3",
133
+ "react-dom": "~19.2.3",
134
+ "vite": "^8.0.13",
135
+ "@dxos/plugin-testing": "0.8.4-main.8baae0fced",
136
+ "@dxos/storybook-utils": "0.8.4-main.8baae0fced",
137
+ "@dxos/random": "0.8.4-main.8baae0fced",
138
+ "@dxos/ui-theme": "0.8.4-main.8baae0fced"
77
139
  },
78
140
  "peerDependencies": {
79
- "effect": "^3.13.3",
80
- "react": "^19.0.0",
81
- "react-dom": "^19.0.0",
82
- "@dxos/react-ui": "0.8.4-main.7ace549",
83
- "@dxos/react-ui-theme": "0.8.4-main.7ace549"
141
+ "effect": "3.20.0",
142
+ "react": "~19.2.3",
143
+ "react-dom": "~19.2.3",
144
+ "@dxos/react-ui": "0.8.4-main.8baae0fced",
145
+ "@dxos/ui-theme": "0.8.4-main.8baae0fced"
84
146
  },
85
147
  "publishConfig": {
86
148
  "access": "public"
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+
7
+ import { meta } from '#meta';
8
+
9
+ export const WnfsPlugin = Plugin.define(meta).pipe(Plugin.make);
10
+
11
+ export default WnfsPlugin;
@@ -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
+ });
@@ -2,88 +2,44 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import * as Function from 'effect/Function';
5
+ import * as Effect from 'effect/Effect';
6
6
 
7
- import {
8
- Capabilities,
9
- Events,
10
- chain,
11
- contributes,
12
- createIntent,
13
- defineModule,
14
- definePlugin,
15
- } from '@dxos/app-framework';
16
- import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
17
- import { MarkdownEvents } from '@dxos/plugin-markdown';
18
- import { type CreateObjectIntent } from '@dxos/plugin-space/types';
7
+ import { Capability, Plugin } from '@dxos/app-framework';
8
+ import { AppPlugin } from '@dxos/app-toolkit';
9
+ import { ClientEvents } from '@dxos/plugin-client';
19
10
 
20
- import { Blockstore, FileUploader, IntentResolver, Markdown, ReactSurface, WnfsCapabilities } from './capabilities';
21
- import { meta } from './meta';
22
- import { translations } from './translations';
23
- import { WnfsAction, WnfsFile } from './types';
11
+ import { Backend, Blockstore, UrlResolver } from '#capabilities';
12
+ import { meta } from '#meta';
13
+ import { translations } from '#translations';
14
+ import { WnfsCapabilities } from '#types';
24
15
 
25
- export const WnfsPlugin = definePlugin(meta, () => [
26
- defineModule({
27
- id: `${meta.id}/module/blockstore`,
16
+ export const WnfsPlugin = Plugin.define(meta).pipe(
17
+ AppPlugin.addTranslationsModule({ translations }),
18
+ Plugin.addModule({
19
+ id: 'blockstore',
28
20
  activatesOn: ClientEvents.ClientReady,
29
21
  activate: Blockstore,
30
22
  }),
31
- defineModule({
32
- id: `${meta.id}/module/instances`,
23
+ Plugin.addModule({
24
+ id: 'instances',
33
25
  activatesOn: ClientEvents.ClientReady,
34
- activate: () => {
35
- const instances: WnfsCapabilities.Instances = {};
36
- return contributes(WnfsCapabilities.Instances, instances);
37
- },
38
- }),
39
- defineModule({
40
- id: `${meta.id}/module/translations`,
41
- activatesOn: Events.SetupTranslations,
42
- activate: () => contributes(Capabilities.Translations, translations),
43
- }),
44
- defineModule({
45
- id: `${meta.id}/module/metadata`,
46
- activatesOn: Events.SetupMetadata,
47
26
  activate: () =>
48
- contributes(Capabilities.Metadata, {
49
- id: WnfsFile.File.typename,
50
- metadata: {
51
- // TODO(wittjosiah): Would be nice if icon could change based on the type of the file.
52
- icon: 'ph--file--regular',
53
- iconHue: 'teal',
54
- inputSchema: WnfsAction.UploadFileSchema,
55
- createObjectIntent: ((props, options) =>
56
- Function.pipe(
57
- createIntent(WnfsAction.Upload, { ...props, space: options.space }),
58
- chain(WnfsAction.Create, {}),
59
- )) satisfies CreateObjectIntent,
60
- addToCollectionOnCreate: true,
61
- },
27
+ Effect.sync(() => {
28
+ const instances: WnfsCapabilities.Instances = {};
29
+ return Capability.contributes(WnfsCapabilities.Instances, instances);
62
30
  }),
63
31
  }),
64
- defineModule({
65
- id: `${meta.id}/module/schema`,
66
- activatesOn: ClientEvents.SetupSchema,
67
- activate: () => contributes(ClientCapabilities.Schema, [WnfsFile.File]),
68
- }),
69
- defineModule({
70
- id: `${meta.id}/module/file-uploader`,
32
+ Plugin.addModule({
33
+ id: 'backend',
71
34
  activatesOn: ClientEvents.ClientReady,
72
- activate: FileUploader,
73
- }),
74
- defineModule({
75
- id: `${meta.id}/module/markdown`,
76
- activatesOn: MarkdownEvents.SetupExtensions,
77
- activate: Markdown,
35
+ activate: Backend,
78
36
  }),
79
- defineModule({
80
- id: `${meta.id}/module/react-surface`,
81
- activatesOn: Events.SetupReactSurface,
82
- activate: ReactSurface,
83
- }),
84
- defineModule({
85
- id: `${meta.id}/module/intent-resolver`,
86
- activatesOn: Events.SetupIntentResolver,
87
- activate: IntentResolver,
37
+ Plugin.addModule({
38
+ id: 'url-resolver',
39
+ activatesOn: ClientEvents.ClientReady,
40
+ activate: UrlResolver,
88
41
  }),
89
- ]);
42
+ Plugin.make,
43
+ );
44
+
45
+ export default WnfsPlugin;
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+
7
+ import { meta } from '#meta';
8
+
9
+ export const WnfsPlugin = Plugin.define(meta).pipe(Plugin.make);
10
+
11
+ export default WnfsPlugin;
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()}/state/queue`;
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
+ );
@@ -2,18 +2,22 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type PluginContext, contributes } from '@dxos/app-framework';
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
6
8
  import { ClientCapabilities } from '@dxos/plugin-client';
7
9
 
8
- import * as Blockstore from '../blockstore';
10
+ import { WnfsCapabilities } from '#types';
9
11
 
10
- import { WnfsCapabilities } from './capabilities';
12
+ import * as Blockstore from '../blockstore';
11
13
 
12
- export default async (context: PluginContext) => {
13
- const client = context.getCapability(ClientCapabilities.Client);
14
- const apiHost = client.config.values.runtime?.services?.edge?.url || 'http://localhost:8787';
15
- const blockstore = Blockstore.create(apiHost);
16
- await blockstore.open();
14
+ export default Capability.makeModule(
15
+ Effect.fnUntraced(function* () {
16
+ const client = yield* Capability.get(ClientCapabilities.Client);
17
+ const apiHost = client.config.values.runtime?.services?.edge?.url || 'http://localhost:8787';
18
+ const blockstore = Blockstore.create(apiHost);
19
+ yield* Effect.tryPromise(() => blockstore.open());
17
20
 
18
- return contributes(WnfsCapabilities.Blockstore, blockstore);
19
- };
21
+ return Capability.contributes(WnfsCapabilities.Blockstore, blockstore);
22
+ }),
23
+ );
@@ -2,12 +2,17 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { lazy } from '@dxos/app-framework';
5
+ import { Capability } from '@dxos/app-framework';
6
+ import { type FileCapabilities } from '@dxos/plugin-file/types';
6
7
 
7
- export const Blockstore = lazy(() => import('./blockstore'));
8
- export const FileUploader = lazy(() => import('./file-uploader'));
9
- export const IntentResolver = lazy(() => import('./intent-resolver'));
10
- export const Markdown = lazy(() => import('./markdown'));
11
- export const ReactSurface = lazy(() => import('./react-surface'));
8
+ export const Backend: Capability.LazyCapability<
9
+ void,
10
+ Capability.Capability<Capability.InterfaceDef<FileCapabilities.Backend>>
11
+ > = Capability.lazy('Backend', () => import('./backend'));
12
12
 
13
- export * from './capabilities';
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
+ );
@@ -7,9 +7,10 @@ import { CID } from 'multiformats';
7
7
  import * as Uint8Arrays from 'uint8arrays';
8
8
  import { AccessKey, PrivateDirectory, PrivateForest, PrivateNode } from 'wnfs';
9
9
 
10
+ import { Obj } from '@dxos/echo';
10
11
  import { type Space } from '@dxos/react-client/echo';
11
12
 
12
- import { type WnfsCapabilities } from '../capabilities';
13
+ import { type WnfsCapabilities } from '#types';
13
14
 
14
15
  import { Rng, store } from './common';
15
16
 
@@ -29,8 +30,10 @@ export const loadWnfs = async ({
29
30
  // TODO(wittjosiah): Remove.
30
31
  // Delete old properties if they exist.
31
32
  if (space.properties.wnfs_access_key !== undefined && space.properties.wnfs_private_forest_cid !== undefined) {
32
- delete space.properties.wnfs_access_key;
33
- delete space.properties.wnfs_private_forest_cid;
33
+ Obj.update(space.properties, (obj) => {
34
+ delete obj['wnfs_access_key'];
35
+ delete obj['wnfs_private_forest_cid'];
36
+ });
34
37
  }
35
38
 
36
39
  const cacheKey = space.properties.wnfs?.privateForestCid;
@@ -65,10 +68,12 @@ const createWnfsDir = async (blockstore: Blockstore, space: Space) => {
65
68
 
66
69
  const cidBytes = await newForest.store(wnfsStore);
67
70
 
68
- space.properties.wnfs = {
69
- accessKey: Uint8Arrays.toString(accessKeyRaw.toBytes(), 'base64'),
70
- privateForestCid: CID.decode(cidBytes).toString(),
71
- };
71
+ Obj.update(space.properties, (obj) => {
72
+ obj.wnfs = {
73
+ accessKey: Uint8Arrays.toString(accessKeyRaw.toBytes(), 'base64'),
74
+ privateForestCid: CID.decode(cidBytes).toString(),
75
+ };
76
+ });
72
77
 
73
78
  return {
74
79
  directory: dir,
@@ -8,9 +8,10 @@ import * as Raw from 'multiformats/codecs/raw';
8
8
  import { sha256 } from 'multiformats/hashes/sha2';
9
9
 
10
10
  import type { Space } from '@dxos/client/echo';
11
+ import { Obj } from '@dxos/echo';
11
12
  import { log } from '@dxos/log';
12
13
 
13
- import { type WnfsCapabilities } from '../capabilities';
14
+ import { type WnfsCapabilities } from '#types';
14
15
 
15
16
  import { Rng, filePath, store } from './common';
16
17
  import { loadWnfs } from './load';
@@ -46,7 +47,9 @@ export const upload = async ({
46
47
  const cidBytes = await updatedForest.store(wnfsStore);
47
48
 
48
49
  // Update the forest pointer on the associated space.
49
- space.properties.wnfs.privateForestCid = CID.decode(cidBytes).toString();
50
+ Obj.update(space.properties, (obj) => {
51
+ obj.wnfs.privateForestCid = CID.decode(cidBytes).toString();
52
+ });
50
53
 
51
54
  // Generate `wnfs://` URL & return the info.
52
55
  const info = {
package/src/index.ts CHANGED
@@ -2,6 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export { WnfsCapabilities } from './capabilities';
5
+ export * from './helpers';
6
6
  export * from './meta';
7
- export * from './WnfsPlugin';
7
+ export * from './types';
package/src/meta.ts CHANGED
@@ -2,12 +2,14 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type PluginMeta } from '@dxos/app-framework';
5
+ import { type Plugin } from '@dxos/app-framework';
6
+ import { meta as fileMeta } from '@dxos/plugin-file';
6
7
  import { trim } from '@dxos/util';
7
8
 
8
- export const meta: PluginMeta = {
9
- id: 'dxos.org/plugin/wnfs',
9
+ export const meta: Plugin.Meta = {
10
+ id: 'org.dxos.plugin.wnfs',
10
11
  name: 'WNFS',
12
+ author: 'DXOS',
11
13
  description: trim`
12
14
  Decentralized file storage using the Web Native File System protocol.
13
15
  Store and sync files with end-to-end encryption across devices without central servers.
@@ -15,4 +17,6 @@ export const meta: PluginMeta = {
15
17
  icon: 'ph--file-cloud--regular',
16
18
  iconHue: 'teal',
17
19
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-wnfs',
20
+ tags: ['labs'],
21
+ dependsOn: [fileMeta.id],
18
22
  };
package/src/plugin.ts ADDED
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+
7
+ import { meta } from './meta';
8
+
9
+ export const WnfsPlugin = Plugin.lazy(meta, () => import('#plugin'));
@@ -4,22 +4,13 @@
4
4
 
5
5
  import { type Resource } from '@dxos/react-ui';
6
6
 
7
- import { meta } from './meta';
8
- import { WnfsFile } from './types';
7
+ import { meta } from '#meta';
9
8
 
10
9
  export const translations = [
11
10
  {
12
11
  'en-US': {
13
- [WnfsFile.File.typename]: {
14
- 'typename label': 'File',
15
- 'object name placeholder': 'New file',
16
- 'rename object label': 'Rename file',
17
- 'delete object label': 'Delete file',
18
- 'object deleted label': 'File deleted',
19
- },
20
12
  [meta.id]: {
21
- 'plugin name': 'Files',
22
- 'file input placeholder': 'Drop a file here, or click to select a file',
13
+ 'plugin.name': 'WNFS',
23
14
  },
24
15
  },
25
16
  },