@diaryx/wasm 1.3.4-dev.b9dba71 → 1.4.0-dev.1c45c8d
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/diaryx_wasm.d.ts +10 -22
- package/diaryx_wasm.js +20 -47
- package/diaryx_wasm_bg.wasm.d.ts +10 -12
- package/package.json +7 -12
- package/README.md +0 -425
package/diaryx_wasm.d.ts
CHANGED
|
@@ -182,11 +182,6 @@ export class DiaryxBackend {
|
|
|
182
182
|
* This avoids JSON serialization overhead for better performance.
|
|
183
183
|
*/
|
|
184
184
|
executeJs(command: any): Promise<any>;
|
|
185
|
-
/**
|
|
186
|
-
* Get the current configuration from root index frontmatter.
|
|
187
|
-
* Config keys are stored as `diaryx_*` properties.
|
|
188
|
-
*/
|
|
189
|
-
getConfig(): Promise<any>;
|
|
190
185
|
/**
|
|
191
186
|
* Check if this backend has native sync support.
|
|
192
187
|
* Always false — sync is handled by the Extism sync plugin loaded at runtime.
|
|
@@ -238,11 +233,6 @@ export class DiaryxBackend {
|
|
|
238
233
|
* Returns data as Uint8Array for efficient handling without base64 encoding.
|
|
239
234
|
*/
|
|
240
235
|
readBinary(path: string): Promise<any>;
|
|
241
|
-
/**
|
|
242
|
-
* Save configuration to root index frontmatter.
|
|
243
|
-
* Config keys are stored as `diaryx_*` properties.
|
|
244
|
-
*/
|
|
245
|
-
saveConfig(config_js: any): Promise<any>;
|
|
246
236
|
/**
|
|
247
237
|
* No-op — CrdtFs is not used; sync handled by Extism plugin.
|
|
248
238
|
*/
|
|
@@ -388,12 +378,10 @@ export interface InitOutput {
|
|
|
388
378
|
readonly diaryxbackend_eventSubscriberCount: (a: number) => number;
|
|
389
379
|
readonly diaryxbackend_execute: (a: number, b: number, c: number) => any;
|
|
390
380
|
readonly diaryxbackend_executeJs: (a: number, b: any) => any;
|
|
391
|
-
readonly diaryxbackend_getConfig: (a: number) => any;
|
|
392
381
|
readonly diaryxbackend_hasNativeSync: (a: number) => number;
|
|
393
382
|
readonly diaryxbackend_offFileSystemEvent: (a: number, b: bigint) => number;
|
|
394
383
|
readonly diaryxbackend_onFileSystemEvent: (a: number, b: any) => bigint;
|
|
395
384
|
readonly diaryxbackend_readBinary: (a: number, b: number, c: number) => any;
|
|
396
|
-
readonly diaryxbackend_saveConfig: (a: number, b: any) => any;
|
|
397
385
|
readonly diaryxbackend_setCrdtEnabled: (a: number, b: number) => void;
|
|
398
386
|
readonly diaryxbackend_writeBinary: (a: number, b: number, c: number, d: any) => any;
|
|
399
387
|
readonly fsafilesystem_fromHandle: (a: any) => number;
|
|
@@ -406,17 +394,17 @@ export interface InitOutput {
|
|
|
406
394
|
readonly today_formatted: (a: number, b: number) => [number, number];
|
|
407
395
|
readonly init: () => void;
|
|
408
396
|
readonly diaryxbackend_isCrdtEnabled: (a: number) => number;
|
|
409
|
-
readonly __wbg_opfsfilesystem_free: (a: number, b: number) => void;
|
|
410
397
|
readonly jsasyncfilesystem_new: (a: any) => number;
|
|
411
|
-
readonly
|
|
412
|
-
readonly
|
|
413
|
-
readonly
|
|
414
|
-
readonly
|
|
415
|
-
readonly
|
|
416
|
-
readonly
|
|
417
|
-
readonly
|
|
418
|
-
readonly
|
|
419
|
-
readonly
|
|
398
|
+
readonly __wbg_opfsfilesystem_free: (a: number, b: number) => void;
|
|
399
|
+
readonly wasm_bindgen__closure__destroy__h8cd94bca3d398e1e: (a: number, b: number) => void;
|
|
400
|
+
readonly wasm_bindgen__closure__destroy__h172a1002de1090db: (a: number, b: number) => void;
|
|
401
|
+
readonly wasm_bindgen__closure__destroy__h03c7db74cf95f03a: (a: number, b: number) => void;
|
|
402
|
+
readonly wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32: (a: number, b: number, c: any) => [number, number];
|
|
403
|
+
readonly wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32_2: (a: number, b: number, c: any) => [number, number];
|
|
404
|
+
readonly wasm_bindgen__convert__closures_____invoke__h82addf46b81c4b92: (a: number, b: number, c: any) => [number, number];
|
|
405
|
+
readonly wasm_bindgen__convert__closures_____invoke__h229fb34ceaba2930: (a: number, b: number, c: any, d: any) => void;
|
|
406
|
+
readonly wasm_bindgen__convert__closures_____invoke__hb73fec669cd9d780: (a: number, b: number, c: any) => void;
|
|
407
|
+
readonly wasm_bindgen__convert__closures_____invoke__hee1eb008cbb50be6: (a: number, b: number, c: any) => void;
|
|
420
408
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
421
409
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
422
410
|
readonly __wbindgen_exn_store: (a: number) => void;
|
package/diaryx_wasm.js
CHANGED
|
@@ -171,15 +171,6 @@ export class DiaryxBackend {
|
|
|
171
171
|
const ret = wasm.diaryxbackend_executeJs(this.__wbg_ptr, command);
|
|
172
172
|
return ret;
|
|
173
173
|
}
|
|
174
|
-
/**
|
|
175
|
-
* Get the current configuration from root index frontmatter.
|
|
176
|
-
* Config keys are stored as `diaryx_*` properties.
|
|
177
|
-
* @returns {Promise<any>}
|
|
178
|
-
*/
|
|
179
|
-
getConfig() {
|
|
180
|
-
const ret = wasm.diaryxbackend_getConfig(this.__wbg_ptr);
|
|
181
|
-
return ret;
|
|
182
|
-
}
|
|
183
174
|
/**
|
|
184
175
|
* Check if this backend has native sync support.
|
|
185
176
|
* Always false — sync is handled by the Extism sync plugin loaded at runtime.
|
|
@@ -256,16 +247,6 @@ export class DiaryxBackend {
|
|
|
256
247
|
const ret = wasm.diaryxbackend_readBinary(this.__wbg_ptr, ptr0, len0);
|
|
257
248
|
return ret;
|
|
258
249
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Save configuration to root index frontmatter.
|
|
261
|
-
* Config keys are stored as `diaryx_*` properties.
|
|
262
|
-
* @param {any} config_js
|
|
263
|
-
* @returns {Promise<any>}
|
|
264
|
-
*/
|
|
265
|
-
saveConfig(config_js) {
|
|
266
|
-
const ret = wasm.diaryxbackend_saveConfig(this.__wbg_ptr, config_js);
|
|
267
|
-
return ret;
|
|
268
|
-
}
|
|
269
250
|
/**
|
|
270
251
|
* No-op — CrdtFs is not used; sync handled by Extism plugin.
|
|
271
252
|
* @param {boolean} _enabled
|
|
@@ -1005,7 +986,7 @@ function __wbg_get_imports() {
|
|
|
1005
986
|
const a = state0.a;
|
|
1006
987
|
state0.a = 0;
|
|
1007
988
|
try {
|
|
1008
|
-
return
|
|
989
|
+
return wasm_bindgen__convert__closures_____invoke__h229fb34ceaba2930(a, state0.b, arg0, arg1);
|
|
1009
990
|
} finally {
|
|
1010
991
|
state0.a = a;
|
|
1011
992
|
}
|
|
@@ -1064,10 +1045,6 @@ function __wbg_get_imports() {
|
|
|
1064
1045
|
const ret = OpfsFileSystem.__wrap(arg0);
|
|
1065
1046
|
return ret;
|
|
1066
1047
|
},
|
|
1067
|
-
__wbg_parse_e9eddd2a82c706eb: function() { return handleError(function (arg0, arg1) {
|
|
1068
|
-
const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
|
|
1069
|
-
return ret;
|
|
1070
|
-
}, arguments); },
|
|
1071
1048
|
__wbg_preventDefault_25a229bfe5c510f8: function(arg0) {
|
|
1072
1049
|
arg0.preventDefault();
|
|
1073
1050
|
},
|
|
@@ -1159,10 +1136,6 @@ function __wbg_get_imports() {
|
|
|
1159
1136
|
const ret = typeof window === 'undefined' ? null : window;
|
|
1160
1137
|
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
1161
1138
|
},
|
|
1162
|
-
__wbg_stringify_5ae93966a84901ac: function() { return handleError(function (arg0) {
|
|
1163
|
-
const ret = JSON.stringify(arg0);
|
|
1164
|
-
return ret;
|
|
1165
|
-
}, arguments); },
|
|
1166
1139
|
__wbg_target_7bc90f314634b37b: function(arg0) {
|
|
1167
1140
|
const ret = arg0.target;
|
|
1168
1141
|
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
@@ -1200,27 +1173,27 @@ function __wbg_get_imports() {
|
|
|
1200
1173
|
}, arguments); },
|
|
1201
1174
|
__wbindgen_cast_0000000000000001: function(arg0, arg1) {
|
|
1202
1175
|
// Cast intrinsic for `Closure(Closure { dtor_idx: 2, function: Function { arguments: [NamedExternref("Event")], shim_idx: 4, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
1203
|
-
const ret = makeMutClosure(arg0, arg1, wasm.
|
|
1176
|
+
const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__h8cd94bca3d398e1e, wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32);
|
|
1204
1177
|
return ret;
|
|
1205
1178
|
},
|
|
1206
1179
|
__wbindgen_cast_0000000000000002: function(arg0, arg1) {
|
|
1207
1180
|
// Cast intrinsic for `Closure(Closure { dtor_idx: 2, function: Function { arguments: [NamedExternref("IDBVersionChangeEvent")], shim_idx: 3, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
1208
|
-
const ret = makeMutClosure(arg0, arg1, wasm.
|
|
1181
|
+
const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__h8cd94bca3d398e1e, wasm_bindgen__convert__closures_____invoke__hb73fec669cd9d780);
|
|
1209
1182
|
return ret;
|
|
1210
1183
|
},
|
|
1211
1184
|
__wbindgen_cast_0000000000000003: function(arg0, arg1) {
|
|
1212
1185
|
// Cast intrinsic for `Closure(Closure { dtor_idx: 2, function: Function { arguments: [NamedExternref("IteratorResult<any>")], shim_idx: 4, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
1213
|
-
const ret = makeMutClosure(arg0, arg1, wasm.
|
|
1186
|
+
const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__h8cd94bca3d398e1e, wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32_2);
|
|
1214
1187
|
return ret;
|
|
1215
1188
|
},
|
|
1216
1189
|
__wbindgen_cast_0000000000000004: function(arg0, arg1) {
|
|
1217
|
-
// Cast intrinsic for `Closure(Closure { dtor_idx:
|
|
1218
|
-
const ret = makeMutClosure(arg0, arg1, wasm.
|
|
1190
|
+
// Cast intrinsic for `Closure(Closure { dtor_idx: 557, function: Function { arguments: [NamedExternref("Event")], shim_idx: 558, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
|
|
1191
|
+
const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__h172a1002de1090db, wasm_bindgen__convert__closures_____invoke__hee1eb008cbb50be6);
|
|
1219
1192
|
return ret;
|
|
1220
1193
|
},
|
|
1221
1194
|
__wbindgen_cast_0000000000000005: function(arg0, arg1) {
|
|
1222
|
-
// Cast intrinsic for `Closure(Closure { dtor_idx:
|
|
1223
|
-
const ret = makeMutClosure(arg0, arg1, wasm.
|
|
1195
|
+
// Cast intrinsic for `Closure(Closure { dtor_idx: 574, function: Function { arguments: [Externref], shim_idx: 575, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
|
|
1196
|
+
const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen__closure__destroy__h03c7db74cf95f03a, wasm_bindgen__convert__closures_____invoke__h82addf46b81c4b92);
|
|
1224
1197
|
return ret;
|
|
1225
1198
|
},
|
|
1226
1199
|
__wbindgen_cast_0000000000000006: function(arg0) {
|
|
@@ -1259,37 +1232,37 @@ function __wbg_get_imports() {
|
|
|
1259
1232
|
};
|
|
1260
1233
|
}
|
|
1261
1234
|
|
|
1262
|
-
function
|
|
1263
|
-
wasm.
|
|
1235
|
+
function wasm_bindgen__convert__closures_____invoke__hb73fec669cd9d780(arg0, arg1, arg2) {
|
|
1236
|
+
wasm.wasm_bindgen__convert__closures_____invoke__hb73fec669cd9d780(arg0, arg1, arg2);
|
|
1264
1237
|
}
|
|
1265
1238
|
|
|
1266
|
-
function
|
|
1267
|
-
wasm.
|
|
1239
|
+
function wasm_bindgen__convert__closures_____invoke__hee1eb008cbb50be6(arg0, arg1, arg2) {
|
|
1240
|
+
wasm.wasm_bindgen__convert__closures_____invoke__hee1eb008cbb50be6(arg0, arg1, arg2);
|
|
1268
1241
|
}
|
|
1269
1242
|
|
|
1270
|
-
function
|
|
1271
|
-
const ret = wasm.
|
|
1243
|
+
function wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32(arg0, arg1, arg2) {
|
|
1244
|
+
const ret = wasm.wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32(arg0, arg1, arg2);
|
|
1272
1245
|
if (ret[1]) {
|
|
1273
1246
|
throw takeFromExternrefTable0(ret[0]);
|
|
1274
1247
|
}
|
|
1275
1248
|
}
|
|
1276
1249
|
|
|
1277
|
-
function
|
|
1278
|
-
const ret = wasm.
|
|
1250
|
+
function wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32_2(arg0, arg1, arg2) {
|
|
1251
|
+
const ret = wasm.wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32_2(arg0, arg1, arg2);
|
|
1279
1252
|
if (ret[1]) {
|
|
1280
1253
|
throw takeFromExternrefTable0(ret[0]);
|
|
1281
1254
|
}
|
|
1282
1255
|
}
|
|
1283
1256
|
|
|
1284
|
-
function
|
|
1285
|
-
const ret = wasm.
|
|
1257
|
+
function wasm_bindgen__convert__closures_____invoke__h82addf46b81c4b92(arg0, arg1, arg2) {
|
|
1258
|
+
const ret = wasm.wasm_bindgen__convert__closures_____invoke__h82addf46b81c4b92(arg0, arg1, arg2);
|
|
1286
1259
|
if (ret[1]) {
|
|
1287
1260
|
throw takeFromExternrefTable0(ret[0]);
|
|
1288
1261
|
}
|
|
1289
1262
|
}
|
|
1290
1263
|
|
|
1291
|
-
function
|
|
1292
|
-
wasm.
|
|
1264
|
+
function wasm_bindgen__convert__closures_____invoke__h229fb34ceaba2930(arg0, arg1, arg2, arg3) {
|
|
1265
|
+
wasm.wasm_bindgen__convert__closures_____invoke__h229fb34ceaba2930(arg0, arg1, arg2, arg3);
|
|
1293
1266
|
}
|
|
1294
1267
|
|
|
1295
1268
|
|
package/diaryx_wasm_bg.wasm.d.ts
CHANGED
|
@@ -15,12 +15,10 @@ export const diaryxbackend_emitFileSystemEvent: (a: number, b: number, c: number
|
|
|
15
15
|
export const diaryxbackend_eventSubscriberCount: (a: number) => number;
|
|
16
16
|
export const diaryxbackend_execute: (a: number, b: number, c: number) => any;
|
|
17
17
|
export const diaryxbackend_executeJs: (a: number, b: any) => any;
|
|
18
|
-
export const diaryxbackend_getConfig: (a: number) => any;
|
|
19
18
|
export const diaryxbackend_hasNativeSync: (a: number) => number;
|
|
20
19
|
export const diaryxbackend_offFileSystemEvent: (a: number, b: bigint) => number;
|
|
21
20
|
export const diaryxbackend_onFileSystemEvent: (a: number, b: any) => bigint;
|
|
22
21
|
export const diaryxbackend_readBinary: (a: number, b: number, c: number) => any;
|
|
23
|
-
export const diaryxbackend_saveConfig: (a: number, b: any) => any;
|
|
24
22
|
export const diaryxbackend_setCrdtEnabled: (a: number, b: number) => void;
|
|
25
23
|
export const diaryxbackend_writeBinary: (a: number, b: number, c: number, d: any) => any;
|
|
26
24
|
export const fsafilesystem_fromHandle: (a: any) => number;
|
|
@@ -33,17 +31,17 @@ export const opfsfilesystem_createWithName: (a: number, b: number) => any;
|
|
|
33
31
|
export const today_formatted: (a: number, b: number) => [number, number];
|
|
34
32
|
export const init: () => void;
|
|
35
33
|
export const diaryxbackend_isCrdtEnabled: (a: number) => number;
|
|
36
|
-
export const __wbg_opfsfilesystem_free: (a: number, b: number) => void;
|
|
37
34
|
export const jsasyncfilesystem_new: (a: any) => number;
|
|
38
|
-
export const
|
|
39
|
-
export const
|
|
40
|
-
export const
|
|
41
|
-
export const
|
|
42
|
-
export const
|
|
43
|
-
export const
|
|
44
|
-
export const
|
|
45
|
-
export const
|
|
46
|
-
export const
|
|
35
|
+
export const __wbg_opfsfilesystem_free: (a: number, b: number) => void;
|
|
36
|
+
export const wasm_bindgen__closure__destroy__h8cd94bca3d398e1e: (a: number, b: number) => void;
|
|
37
|
+
export const wasm_bindgen__closure__destroy__h172a1002de1090db: (a: number, b: number) => void;
|
|
38
|
+
export const wasm_bindgen__closure__destroy__h03c7db74cf95f03a: (a: number, b: number) => void;
|
|
39
|
+
export const wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32: (a: number, b: number, c: any) => [number, number];
|
|
40
|
+
export const wasm_bindgen__convert__closures_____invoke__h9bd686ed59a4fd32_2: (a: number, b: number, c: any) => [number, number];
|
|
41
|
+
export const wasm_bindgen__convert__closures_____invoke__h82addf46b81c4b92: (a: number, b: number, c: any) => [number, number];
|
|
42
|
+
export const wasm_bindgen__convert__closures_____invoke__h229fb34ceaba2930: (a: number, b: number, c: any, d: any) => void;
|
|
43
|
+
export const wasm_bindgen__convert__closures_____invoke__hb73fec669cd9d780: (a: number, b: number, c: any) => void;
|
|
44
|
+
export const wasm_bindgen__convert__closures_____invoke__hee1eb008cbb50be6: (a: number, b: number, c: any) => void;
|
|
47
45
|
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
48
46
|
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
49
47
|
export const __wbindgen_exn_store: (a: number) => void;
|
package/package.json
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diaryx/wasm",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "https://github.com/diaryx-org/diaryx"
|
|
10
|
-
},
|
|
4
|
+
"version": "1.4.0-dev.1c45c8d",
|
|
5
|
+
"main": "diaryx_wasm.js",
|
|
6
|
+
"types": "diaryx_wasm.d.ts",
|
|
11
7
|
"files": [
|
|
12
8
|
"diaryx_wasm.js",
|
|
13
9
|
"diaryx_wasm_bg.js",
|
|
14
10
|
"diaryx_wasm.d.ts",
|
|
15
11
|
"diaryx_wasm_bg.wasm.d.ts"
|
|
16
12
|
],
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
]
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/diaryx-org/diaryx"
|
|
16
|
+
}
|
|
22
17
|
}
|
package/README.md
DELETED
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: diaryx_wasm
|
|
3
|
-
description: WASM bindings for diaryx_core
|
|
4
|
-
part_of: '[README](/crates/README.md)'
|
|
5
|
-
audience:
|
|
6
|
-
- developers
|
|
7
|
-
contents:
|
|
8
|
-
- '[README](/crates/diaryx_wasm/src/README.md)'
|
|
9
|
-
attachments:
|
|
10
|
-
- '[Cargo.toml](/crates/diaryx_wasm/Cargo.toml)'
|
|
11
|
-
- '[build.rs](/crates/diaryx_wasm/build.rs)'
|
|
12
|
-
exclude:
|
|
13
|
-
- '*.lock'
|
|
14
|
-
- '*.db'
|
|
15
|
-
- pkg/**
|
|
16
|
-
---
|
|
17
|
-
# diaryx_wasm
|
|
18
|
-
|
|
19
|
-
WebAssembly bindings for `diaryx_core`, used by the web frontend in `apps/web`.
|
|
20
|
-
|
|
21
|
-
## Building
|
|
22
|
-
|
|
23
|
-
To build the WebAssembly module:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
wasm-pack build --target web --out-dir ../../apps/web/src/lib/wasm
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Testing
|
|
30
|
-
|
|
31
|
-
Run browser filesystem integration tests (wasm + browser):
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
nix develop -c wasm-pack test --headless --chrome crates/diaryx_wasm
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Current filesystem test suites live in:
|
|
38
|
-
|
|
39
|
-
- `crates/diaryx_wasm/tests/opfs_fs.rs`
|
|
40
|
-
- `crates/diaryx_wasm/tests/fs_trait_parity.rs`
|
|
41
|
-
|
|
42
|
-
`fs_trait_parity.rs` runs the same contract checks across:
|
|
43
|
-
|
|
44
|
-
- `OpfsFileSystem`
|
|
45
|
-
- `IndexedDbFileSystem`
|
|
46
|
-
- `FsaFileSystem`
|
|
47
|
-
|
|
48
|
-
## Architecture
|
|
49
|
-
|
|
50
|
-
`diaryx_wasm` depends only on `diaryx_core`. The main entry point is `DiaryxBackend`,
|
|
51
|
-
which provides a unified command API (`execute()`/`executeJs()`) backed by native
|
|
52
|
-
browser storage (OPFS, IndexedDB, File System Access API).
|
|
53
|
-
|
|
54
|
-
Sync and publish functionality are provided by Extism guest plugins
|
|
55
|
-
(`diaryx_sync.wasm`, `diaryx_publish.wasm`) loaded at runtime by the browser
|
|
56
|
-
plugin manager. CRDT commands are routed to the sync plugin via the frontend
|
|
57
|
-
command router before reaching the WASM backend.
|
|
58
|
-
|
|
59
|
-
### Storage Backends
|
|
60
|
-
|
|
61
|
-
Unlike the CLI and Tauri backends which use `RealFileSystem` (native filesystem),
|
|
62
|
-
the WASM backend supports several browser storage backends:
|
|
63
|
-
|
|
64
|
-
- **OPFS** — Origin Private File System (default)
|
|
65
|
-
- **IndexedDB** — IndexedDB-based filesystem
|
|
66
|
-
- **File System Access** — User-selected directory on the real filesystem
|
|
67
|
-
- **In-Memory** — Used for guest mode in share sessions
|
|
68
|
-
- **JavaScript** — Bridged to external JS filesystem (Node.js, Obsidian, Electron)
|
|
69
|
-
|
|
70
|
-
## API Reference
|
|
71
|
-
|
|
72
|
-
### DiaryxValidation
|
|
73
|
-
|
|
74
|
-
Validates workspace link integrity and fixes issues.
|
|
75
|
-
|
|
76
|
-
```javascript
|
|
77
|
-
import init, { DiaryxValidation } from "./wasm/diaryx_wasm.js";
|
|
78
|
-
|
|
79
|
-
await init();
|
|
80
|
-
const validation = new DiaryxValidation();
|
|
81
|
-
|
|
82
|
-
// Validate entire workspace
|
|
83
|
-
const result = validation.validate("workspace");
|
|
84
|
-
console.log(`Checked ${result.files_checked} files`);
|
|
85
|
-
console.log(`Errors: ${result.errors.length}`);
|
|
86
|
-
console.log(`Warnings: ${result.warnings.length}`);
|
|
87
|
-
|
|
88
|
-
// Validate single file
|
|
89
|
-
const fileResult = validation.validate_file("workspace/notes/my-note.md");
|
|
90
|
-
|
|
91
|
-
// Fix all issues
|
|
92
|
-
const fixSummary = validation.fix_all(result);
|
|
93
|
-
console.log(
|
|
94
|
-
`Fixed: ${fixSummary.total_fixed}, Failed: ${fixSummary.total_failed}`,
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
// Fix individual issues
|
|
98
|
-
validation.fix_broken_part_of("workspace/broken.md");
|
|
99
|
-
validation.fix_broken_contents_ref("workspace/index.md", "missing.md");
|
|
100
|
-
validation.fix_unlisted_file("workspace/index.md", "workspace/unlisted.md");
|
|
101
|
-
validation.fix_missing_part_of("workspace/orphan.md", "workspace/index.md");
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
#### Validation Errors
|
|
105
|
-
|
|
106
|
-
- `BrokenPartOf` - `part_of` points to non-existent file
|
|
107
|
-
- `BrokenContentsRef` - `contents` references non-existent file
|
|
108
|
-
- `BrokenAttachment` - `attachments` references non-existent file
|
|
109
|
-
|
|
110
|
-
#### Validation Warnings
|
|
111
|
-
|
|
112
|
-
- `OrphanFile` - Markdown file not in any index's `contents`
|
|
113
|
-
- `UnlinkedEntry` - File/directory not in contents hierarchy
|
|
114
|
-
- `CircularReference` - Circular reference in hierarchy
|
|
115
|
-
- `NonPortablePath` - Path contains absolute or `.`/`..` components
|
|
116
|
-
- `MultipleIndexes` - Multiple index files in same directory
|
|
117
|
-
- `OrphanBinaryFile` - Binary file not in any index's `attachments`
|
|
118
|
-
- `MissingPartOf` - Non-index file has no `part_of`
|
|
119
|
-
|
|
120
|
-
#### Exclude Patterns
|
|
121
|
-
|
|
122
|
-
Use `exclude` in frontmatter to suppress warnings. Patterns inherit up the `part_of` chain:
|
|
123
|
-
|
|
124
|
-
```yaml
|
|
125
|
-
exclude:
|
|
126
|
-
- "LICENSE.md"
|
|
127
|
-
- "*.lock"
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Legacy API
|
|
131
|
-
|
|
132
|
-
For backwards compatibility, standalone functions are also exported:
|
|
133
|
-
|
|
134
|
-
```javascript
|
|
135
|
-
import {
|
|
136
|
-
validate_workspace,
|
|
137
|
-
validate_file,
|
|
138
|
-
fix_all_validation_issues,
|
|
139
|
-
} from "./wasm/diaryx_wasm.js";
|
|
140
|
-
|
|
141
|
-
const result = validate_workspace("workspace");
|
|
142
|
-
const fixSummary = fix_all_validation_issues(result);
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### DiaryxAsyncFilesystem
|
|
146
|
-
|
|
147
|
-
Async filesystem operations that return JavaScript Promises. This is useful for consistent async/await patterns in JavaScript and future integration with truly async storage (e.g., IndexedDB).
|
|
148
|
-
|
|
149
|
-
```javascript
|
|
150
|
-
import init, { DiaryxAsyncFilesystem } from "./wasm/diaryx_wasm.js";
|
|
151
|
-
|
|
152
|
-
await init();
|
|
153
|
-
const asyncFs = new DiaryxAsyncFilesystem();
|
|
154
|
-
|
|
155
|
-
// All methods return Promises
|
|
156
|
-
const content = await asyncFs.read_file("workspace/README.md");
|
|
157
|
-
await asyncFs.write_file("workspace/new.md", "# New File");
|
|
158
|
-
const exists = await asyncFs.file_exists("workspace/new.md");
|
|
159
|
-
|
|
160
|
-
// Directory operations
|
|
161
|
-
await asyncFs.create_dir_all("workspace/notes/2024");
|
|
162
|
-
const isDir = await asyncFs.is_dir("workspace/notes");
|
|
163
|
-
|
|
164
|
-
// List files
|
|
165
|
-
const mdFiles = await asyncFs.list_md_files("workspace");
|
|
166
|
-
console.log(`Found ${mdFiles.count} markdown files:`, mdFiles.files);
|
|
167
|
-
|
|
168
|
-
// Recursive listing
|
|
169
|
-
const allMd = await asyncFs.list_md_files_recursive("workspace");
|
|
170
|
-
const allFiles = await asyncFs.list_all_files_recursive("workspace");
|
|
171
|
-
|
|
172
|
-
// Binary file operations
|
|
173
|
-
const data = await asyncFs.read_binary("workspace/image.png");
|
|
174
|
-
await asyncFs.write_binary("workspace/copy.png", data);
|
|
175
|
-
|
|
176
|
-
// Bulk operations for IndexedDB sync
|
|
177
|
-
const backupData = await asyncFs.get_backup_data();
|
|
178
|
-
// ... persist to IndexedDB ...
|
|
179
|
-
await asyncFs.restore_from_backup(backupData);
|
|
180
|
-
|
|
181
|
-
// Load/export files
|
|
182
|
-
await asyncFs.load_files([
|
|
183
|
-
["workspace/README.md", "# Hello"],
|
|
184
|
-
["workspace/notes.md", "# Notes"],
|
|
185
|
-
]);
|
|
186
|
-
const entries = await asyncFs.export_files();
|
|
187
|
-
|
|
188
|
-
// Clear filesystem
|
|
189
|
-
await asyncFs.clear();
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
#### Async vs Sync Filesystem
|
|
193
|
-
|
|
194
|
-
- `DiaryxFilesystem` - Synchronous methods, returns values directly
|
|
195
|
-
- `DiaryxAsyncFilesystem` - All methods return Promises
|
|
196
|
-
|
|
197
|
-
While the underlying `InMemoryFileSystem` is synchronous, `DiaryxAsyncFilesystem` provides a Promise-based API that:
|
|
198
|
-
|
|
199
|
-
1. Enables consistent async/await patterns in JavaScript
|
|
200
|
-
2. Allows for future integration with truly async operations
|
|
201
|
-
3. Works well with JavaScript's event loop
|
|
202
|
-
|
|
203
|
-
### Diaryx (Command API with CRDT)
|
|
204
|
-
|
|
205
|
-
The `Diaryx` class provides a unified command API that includes CRDT operations for real-time collaboration. Commands are executed via `execute()` (returns typed result) or `executeJs()` (returns JS-friendly object).
|
|
206
|
-
|
|
207
|
-
```javascript
|
|
208
|
-
import init, { Diaryx } from "./wasm/diaryx_wasm.js";
|
|
209
|
-
|
|
210
|
-
await init();
|
|
211
|
-
const diaryx = new Diaryx();
|
|
212
|
-
|
|
213
|
-
// All CRDT commands use the execute/executeJs pattern
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
#### CRDT Workspace Operations
|
|
217
|
-
|
|
218
|
-
```javascript
|
|
219
|
-
// Set file metadata in the CRDT workspace
|
|
220
|
-
await diaryx.executeJs({
|
|
221
|
-
type: "SetFileMetadata",
|
|
222
|
-
path: "notes/my-note.md",
|
|
223
|
-
metadata: {
|
|
224
|
-
title: "My Note",
|
|
225
|
-
audience: ["public"],
|
|
226
|
-
part_of: "README.md",
|
|
227
|
-
},
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
// Get file metadata
|
|
231
|
-
const result = await diaryx.executeJs({
|
|
232
|
-
type: "GetFileMetadata",
|
|
233
|
-
path: "notes/my-note.md",
|
|
234
|
-
});
|
|
235
|
-
console.log(result.metadata); // { title: "My Note", ... }
|
|
236
|
-
|
|
237
|
-
// List all files in workspace
|
|
238
|
-
const files = await diaryx.executeJs({ type: "ListFiles" });
|
|
239
|
-
console.log(files.files); // ["notes/my-note.md", ...]
|
|
240
|
-
|
|
241
|
-
// Remove a file from workspace
|
|
242
|
-
await diaryx.executeJs({
|
|
243
|
-
type: "RemoveFile",
|
|
244
|
-
path: "notes/my-note.md",
|
|
245
|
-
});
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
#### CRDT Body Document Operations
|
|
249
|
-
|
|
250
|
-
```javascript
|
|
251
|
-
// Set document body content
|
|
252
|
-
await diaryx.executeJs({
|
|
253
|
-
type: "SetBody",
|
|
254
|
-
path: "notes/my-note.md",
|
|
255
|
-
content: "# Hello World\n\nThis is my note.",
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
// Get document body
|
|
259
|
-
const body = await diaryx.executeJs({
|
|
260
|
-
type: "GetBody",
|
|
261
|
-
path: "notes/my-note.md",
|
|
262
|
-
});
|
|
263
|
-
console.log(body.content);
|
|
264
|
-
|
|
265
|
-
// Insert text at position (collaborative editing)
|
|
266
|
-
await diaryx.executeJs({
|
|
267
|
-
type: "InsertAt",
|
|
268
|
-
path: "notes/my-note.md",
|
|
269
|
-
position: 0,
|
|
270
|
-
text: "Prefix: ",
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
// Delete text range
|
|
274
|
-
await diaryx.executeJs({
|
|
275
|
-
type: "DeleteRange",
|
|
276
|
-
path: "notes/my-note.md",
|
|
277
|
-
start: 0,
|
|
278
|
-
end: 8,
|
|
279
|
-
});
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
#### CRDT Sync Operations
|
|
283
|
-
|
|
284
|
-
For synchronizing with Hocuspocus or other Y.js-compatible servers:
|
|
285
|
-
|
|
286
|
-
```javascript
|
|
287
|
-
// Get sync state (state vector) for initial handshake
|
|
288
|
-
const syncState = await diaryx.executeJs({
|
|
289
|
-
type: "GetSyncState",
|
|
290
|
-
doc_type: "workspace", // or "body"
|
|
291
|
-
doc_name: null, // required for "body" type
|
|
292
|
-
});
|
|
293
|
-
const stateVector = syncState.state_vector; // Uint8Array
|
|
294
|
-
|
|
295
|
-
// Apply remote update from server
|
|
296
|
-
await diaryx.executeJs({
|
|
297
|
-
type: "ApplyRemoteUpdate",
|
|
298
|
-
doc_type: "workspace",
|
|
299
|
-
doc_name: null,
|
|
300
|
-
update: remoteUpdateBytes, // Uint8Array from WebSocket
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// Encode full state to send to server
|
|
304
|
-
const state = await diaryx.executeJs({
|
|
305
|
-
type: "EncodeState",
|
|
306
|
-
doc_type: "workspace",
|
|
307
|
-
doc_name: null,
|
|
308
|
-
});
|
|
309
|
-
sendToServer(state.state); // Uint8Array
|
|
310
|
-
|
|
311
|
-
// Encode incremental update since a state vector
|
|
312
|
-
const diff = await diaryx.executeJs({
|
|
313
|
-
type: "EncodeStateAsUpdate",
|
|
314
|
-
doc_type: "workspace",
|
|
315
|
-
doc_name: null,
|
|
316
|
-
state_vector: remoteStateVector, // Uint8Array
|
|
317
|
-
});
|
|
318
|
-
sendToServer(diff.update); // Uint8Array
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
#### Version History
|
|
322
|
-
|
|
323
|
-
```javascript
|
|
324
|
-
// Get version history for a document
|
|
325
|
-
const history = await diaryx.executeJs({
|
|
326
|
-
type: "GetHistory",
|
|
327
|
-
doc_type: "workspace", // or "body"
|
|
328
|
-
doc_name: null, // required for "body" type
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
for (const entry of history.entries) {
|
|
332
|
-
console.log(`Version ${entry.version} at ${entry.timestamp}`);
|
|
333
|
-
console.log(` Origin: ${entry.origin}`); // "local" or "remote"
|
|
334
|
-
console.log(` Size: ${entry.update.length} bytes`);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Restore to a specific version (time travel)
|
|
338
|
-
await diaryx.executeJs({
|
|
339
|
-
type: "RestoreToVersion",
|
|
340
|
-
doc_type: "workspace",
|
|
341
|
-
doc_name: null,
|
|
342
|
-
version: 5,
|
|
343
|
-
});
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
#### Document Types
|
|
347
|
-
|
|
348
|
-
CRDT operations use `doc_type` to specify which document to operate on:
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
| doc_type | doc_name | Description |
|
|
352
|
-
| ----------- | --------- | ------------------------------------------ |
|
|
353
|
-
| `workspace` | `null` | The workspace file hierarchy metadata |
|
|
354
|
-
| `body` | file path | Per-file body content (e.g., `notes/a.md`) |
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
## Node.js / Obsidian / Electron Usage
|
|
358
|
-
|
|
359
|
-
The `@diaryx/wasm-node` npm package is a build of this crate without browser-specific storage backends. It's published automatically by CI and works in any JavaScript environment that supports WebAssembly.
|
|
360
|
-
|
|
361
|
-
### Setup
|
|
362
|
-
|
|
363
|
-
```javascript
|
|
364
|
-
import init, { DiaryxBackend } from '@diaryx/wasm-node';
|
|
365
|
-
import fs from 'fs';
|
|
366
|
-
|
|
367
|
-
// Load WASM binary and initialize
|
|
368
|
-
const wasmPath = new URL('./diaryx_wasm_bg.wasm', import.meta.url);
|
|
369
|
-
await init(fs.readFileSync(wasmPath));
|
|
370
|
-
|
|
371
|
-
// Create backend with JavaScript filesystem callbacks
|
|
372
|
-
const backend = DiaryxBackend.createFromJsFileSystem({
|
|
373
|
-
readToString: (path) => fs.promises.readFile(path, 'utf8'),
|
|
374
|
-
writeFile: (path, content) => fs.promises.writeFile(path, content),
|
|
375
|
-
exists: (path) => fs.promises.access(path).then(() => true).catch(() => false),
|
|
376
|
-
isDir: (path) => fs.promises.stat(path).then(s => s.isDirectory()).catch(() => false),
|
|
377
|
-
listFiles: (dir) => fs.promises.readdir(dir),
|
|
378
|
-
listMdFiles: (dir) => fs.promises.readdir(dir).then(f => f.filter(n => n.endsWith('.md'))),
|
|
379
|
-
createDirAll: (path) => fs.promises.mkdir(path, { recursive: true }),
|
|
380
|
-
moveFile: (from, to) => fs.promises.rename(from, to),
|
|
381
|
-
deleteFile: (path) => fs.promises.unlink(path),
|
|
382
|
-
readBinary: (path) => fs.promises.readFile(path),
|
|
383
|
-
writeBinary: (path, data) => fs.promises.writeFile(path, data),
|
|
384
|
-
});
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
### Obsidian Plugin Integration
|
|
388
|
-
|
|
389
|
-
For Obsidian plugins, bridge the Vault adapter API:
|
|
390
|
-
|
|
391
|
-
```javascript
|
|
392
|
-
const backend = DiaryxBackend.createFromJsFileSystem({
|
|
393
|
-
readToString: (path) => app.vault.adapter.read(path),
|
|
394
|
-
writeFile: (path, content) => app.vault.adapter.write(path, content),
|
|
395
|
-
exists: (path) => app.vault.adapter.exists(path),
|
|
396
|
-
isDir: (path) => app.vault.adapter.stat(path).then(s => s?.type === 'folder'),
|
|
397
|
-
listFiles: (dir) => app.vault.adapter.list(dir).then(r => [...r.files, ...r.folders]),
|
|
398
|
-
listMdFiles: (dir) => app.vault.adapter.list(dir).then(r => r.files.filter(f => f.endsWith('.md'))),
|
|
399
|
-
createDirAll: (path) => app.vault.adapter.mkdir(path),
|
|
400
|
-
moveFile: (from, to) => app.vault.adapter.rename(from, to),
|
|
401
|
-
deleteFile: (path) => app.vault.adapter.remove(path),
|
|
402
|
-
readBinary: (path) => app.vault.adapter.readBinary(path),
|
|
403
|
-
writeBinary: (path, data) => app.vault.adapter.writeBinary(path, data),
|
|
404
|
-
});
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
### Reacting to External File Moves
|
|
408
|
-
|
|
409
|
-
When an external tool (Obsidian, VS Code, etc.) has already moved a file, use `SyncMoveMetadata` to update the workspace hierarchy metadata without re-doing the filesystem move:
|
|
410
|
-
|
|
411
|
-
```javascript
|
|
412
|
-
// Obsidian fires this after a file is moved/renamed
|
|
413
|
-
app.vault.on('rename', async (file, oldPath) => {
|
|
414
|
-
await backend.executeJs({
|
|
415
|
-
type: 'SyncMoveMetadata',
|
|
416
|
-
params: { old_path: oldPath, new_path: file.path }
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
This updates `contents` in the old and new parent indexes and `part_of` in the moved file.
|
|
422
|
-
|
|
423
|
-
## Error Handling
|
|
424
|
-
|
|
425
|
-
All methods return `Result<T, JsValue>` for JavaScript interop. Errors are converted to JavaScript exceptions with descriptive messages.
|