@silverbulletmd/silverbullet 2.5.3 → 2.6.1

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 (90) hide show
  1. package/README.md +4 -5
  2. package/client/asset_bundle/bundle.ts +3 -9
  3. package/client/data/datastore.ts +4 -5
  4. package/client/markdown_parser/constants.ts +3 -2
  5. package/client/plugos/hooks/code_widget.ts +3 -5
  6. package/client/plugos/hooks/command.ts +8 -8
  7. package/client/plugos/hooks/document_editor.ts +10 -12
  8. package/client/plugos/hooks/event.ts +33 -36
  9. package/client/plugos/hooks/mq.ts +17 -17
  10. package/client/plugos/hooks/plug_namespace.ts +3 -5
  11. package/client/plugos/hooks/slash_command.ts +12 -27
  12. package/client/plugos/hooks/syscall.ts +3 -3
  13. package/client/plugos/manifest_cache.ts +22 -15
  14. package/client/plugos/plug.ts +2 -5
  15. package/client/plugos/plug_compile.ts +67 -65
  16. package/client/plugos/protocol.ts +28 -28
  17. package/client/plugos/proxy_fetch.ts +7 -6
  18. package/client/plugos/sandboxes/worker_sandbox.ts +16 -15
  19. package/client/plugos/syscalls/asset.ts +1 -3
  20. package/client/plugos/syscalls/code_widget.ts +1 -3
  21. package/client/plugos/syscalls/config.ts +1 -5
  22. package/client/plugos/syscalls/datastore.ts +1 -1
  23. package/client/plugos/syscalls/editor.ts +63 -60
  24. package/client/plugos/syscalls/event.ts +9 -12
  25. package/client/plugos/syscalls/fetch.ts +30 -22
  26. package/client/plugos/syscalls/index.ts +10 -1
  27. package/client/plugos/syscalls/jsonschema.ts +72 -32
  28. package/client/plugos/syscalls/language.ts +9 -5
  29. package/client/plugos/syscalls/markdown.ts +29 -7
  30. package/client/plugos/syscalls/mq.ts +3 -11
  31. package/client/plugos/syscalls/service_registry.ts +1 -4
  32. package/client/plugos/syscalls/shell.ts +2 -5
  33. package/client/plugos/syscalls/sync.ts +69 -60
  34. package/client/plugos/syscalls/system.ts +2 -3
  35. package/client/plugos/system.ts +4 -10
  36. package/client/plugos/worker_runtime.ts +4 -3
  37. package/client/space_lua/aggregates.ts +632 -59
  38. package/client/space_lua/ast.ts +21 -9
  39. package/client/space_lua/ast_narrow.ts +4 -2
  40. package/client/space_lua/eval.ts +842 -536
  41. package/client/space_lua/labels.ts +6 -11
  42. package/client/space_lua/liq_null.ts +6 -0
  43. package/client/space_lua/numeric.ts +5 -8
  44. package/client/space_lua/parse.ts +290 -169
  45. package/client/space_lua/query_collection.ts +213 -149
  46. package/client/space_lua/render_lua_markdown.ts +369 -0
  47. package/client/space_lua/rp.ts +5 -4
  48. package/client/space_lua/runtime.ts +245 -142
  49. package/client/space_lua/stdlib/format.ts +34 -20
  50. package/client/space_lua/stdlib/js.ts +3 -7
  51. package/client/space_lua/stdlib/load.ts +1 -3
  52. package/client/space_lua/stdlib/math.ts +15 -14
  53. package/client/space_lua/stdlib/net.ts +25 -15
  54. package/client/space_lua/stdlib/os.ts +76 -85
  55. package/client/space_lua/stdlib/pattern.ts +28 -35
  56. package/client/space_lua/stdlib/prng.ts +15 -12
  57. package/client/space_lua/stdlib/space_lua.ts +16 -17
  58. package/client/space_lua/stdlib/string.ts +7 -17
  59. package/client/space_lua/stdlib/string_pack.ts +23 -19
  60. package/client/space_lua/stdlib/table.ts +5 -9
  61. package/client/space_lua/stdlib.ts +20 -30
  62. package/client/space_lua/tonumber.ts +79 -40
  63. package/client/space_lua/util.ts +14 -10
  64. package/dist/plug-compile.js +44 -41
  65. package/package.json +24 -22
  66. package/plug-api/lib/async.ts +19 -6
  67. package/plug-api/lib/crypto.ts +5 -6
  68. package/plug-api/lib/dates.ts +15 -7
  69. package/plug-api/lib/json.ts +10 -4
  70. package/plug-api/lib/ref.ts +18 -18
  71. package/plug-api/lib/resolve.ts +7 -11
  72. package/plug-api/lib/tags.ts +13 -4
  73. package/plug-api/lib/transclusion.ts +6 -17
  74. package/plug-api/lib/tree.ts +115 -43
  75. package/plug-api/lib/yaml.ts +25 -15
  76. package/plug-api/syscalls/asset.ts +1 -1
  77. package/plug-api/syscalls/config.ts +1 -4
  78. package/plug-api/syscalls/editor.ts +14 -14
  79. package/plug-api/syscalls/jsonschema.ts +1 -3
  80. package/plug-api/syscalls/lua.ts +3 -9
  81. package/plug-api/syscalls/mq.ts +1 -4
  82. package/plug-api/syscalls/shell.ts +4 -1
  83. package/plug-api/syscalls/space.ts +3 -10
  84. package/plug-api/syscalls/system.ts +1 -4
  85. package/plug-api/syscalls/yaml.ts +2 -6
  86. package/plug-api/types/client.ts +16 -1
  87. package/plug-api/types/event.ts +6 -4
  88. package/plug-api/types/manifest.ts +8 -9
  89. package/plugs/builtin_plugs.ts +2 -2
  90. package/dist/worker_runtime_bundle.js +0 -233
@@ -7,24 +7,30 @@ import * as esbuild from "esbuild";
7
7
  import { bundleAssets } from "../asset_bundle/builder.ts";
8
8
  import type { Manifest } from "./types.ts";
9
9
 
10
- import { existsSync } from "node:fs";
11
-
12
- // Resolve the pre-built worker_runtime bundle path
13
- // When running from source: ../../dist/worker_runtime_bundle.js (from client/plugos/)
14
- // When bundled: ./worker_runtime_bundle.js (from dist/)
15
- const currentDir = import.meta.dirname;
16
- const bundledPath = path.join(currentDir, "worker_runtime_bundle.js");
17
- const sourcePath = path.join(currentDir, "../../dist/worker_runtime_bundle.js");
18
- const workerRuntimeBundlePath = existsSync(bundledPath)
19
- ? bundledPath
20
- : sourcePath;
10
+ // When bundled by build_plug_compile.ts, this is replaced with the pre-bundled
11
+ // worker runtime JS. When running from source, it's undefined and esbuild
12
+ // resolves the .ts file directly (it handles TypeScript natively).
13
+ declare const __EMBEDDED_WORKER_RUNTIME_JS__: string | undefined;
21
14
 
22
15
  const workerRuntimePlugin: esbuild.Plugin = {
23
16
  name: "worker-runtime",
24
17
  setup(build) {
25
- build.onResolve({ filter: /^worker-runtime$/ }, () => ({
26
- path: workerRuntimeBundlePath,
27
- }));
18
+ if (typeof __EMBEDDED_WORKER_RUNTIME_JS__ !== "undefined") {
19
+ // Bundled CLI: serve pre-bundled JS from the embedded constant
20
+ build.onResolve({ filter: /^worker-runtime$/ }, () => ({
21
+ path: "worker-runtime",
22
+ namespace: "worker-runtime",
23
+ }));
24
+ build.onLoad({ filter: /.*/, namespace: "worker-runtime" }, () => ({
25
+ contents: __EMBEDDED_WORKER_RUNTIME_JS__,
26
+ loader: "js",
27
+ }));
28
+ } else {
29
+ // From source: point directly at the .ts file, esbuild handles it
30
+ build.onResolve({ filter: /^worker-runtime$/ }, () => ({
31
+ path: path.join(import.meta.dirname, "worker_runtime.ts"),
32
+ }));
33
+ }
28
34
  },
29
35
  };
30
36
 
@@ -50,7 +56,7 @@ export async function compileManifest(
50
56
  // Assets
51
57
  const assetsBundle = await bundleAssets(
52
58
  path.resolve(rootPath),
53
- manifest.assets as string[] || [],
59
+ (manifest.assets as string[]) || [],
54
60
  );
55
61
  manifest.assets = assetsBundle.toJSON();
56
62
 
@@ -63,34 +69,32 @@ export async function compileManifest(
63
69
  import { setupMessageListener } from "worker-runtime";
64
70
 
65
71
  // Imports
66
- ${
67
- Object.entries(manifest.functions).map(([funcName, def]) => {
68
- if (!def.path) {
69
- return "";
70
- }
71
- let [filePath, jsFunctionName] = def.path.split(":");
72
- // Resolve path
73
- filePath = path.join(rootPath, filePath);
74
-
75
- return `import {${jsFunctionName} as ${funcName}} from "${
76
- // Replacing \ with / for Windows
77
- path.resolve(filePath).replaceAll(
78
- "\\",
79
- "\\\\",
80
- )}";\n`;
81
- }).join("")
82
- }
72
+ ${Object.entries(manifest.functions)
73
+ .map(([funcName, def]) => {
74
+ if (!def.path) {
75
+ return "";
76
+ }
77
+ let [filePath, jsFunctionName] = def.path.split(":");
78
+ // Resolve path
79
+ filePath = path.join(rootPath, filePath);
80
+
81
+ return `import {${jsFunctionName} as ${funcName}} from "${
82
+ // Replacing \ with / for Windows
83
+ path.resolve(filePath).replaceAll("\\", "\\\\")
84
+ }";\n`;
85
+ })
86
+ .join("")}
83
87
 
84
88
  // Function mapping
85
89
  const functionMapping = {
86
- ${
87
- Object.entries(manifest.functions).map(([funcName, def]) => {
88
- if (!def.path) {
89
- return "";
90
- }
91
- return ` ${funcName}: ${funcName},\n`;
92
- }).join("")
93
- }
90
+ ${Object.entries(manifest.functions)
91
+ .map(([funcName, def]) => {
92
+ if (!def.path) {
93
+ return "";
94
+ }
95
+ return ` ${funcName}: ${funcName},\n`;
96
+ })
97
+ .join("")}
94
98
  };
95
99
 
96
100
  // Manifest
@@ -130,10 +134,10 @@ setupMessageListener(functionMapping, manifest, self.postMessage);
130
134
  let jsCode = await readFile(outFile, "utf-8");
131
135
  jsCode = patchBundledJS(jsCode);
132
136
  await writeFile(outFile, jsCode, "utf-8");
133
-
137
+
134
138
  // Clean up temp directory
135
139
  await rm(tempDir, { recursive: true, force: true });
136
-
140
+
137
141
  console.log(`Plug ${manifest.name} written to ${outFile}.`);
138
142
  return outFile;
139
143
  }
@@ -155,19 +159,17 @@ export async function compileManifests(
155
159
  await mkdir(dist, { recursive: true });
156
160
  const startTime = Date.now();
157
161
  // Build all plugs in parallel
158
- await Promise.all(manifestFiles.map(async (plugManifestPath) => {
159
- const manifestPath = plugManifestPath as string;
160
- try {
161
- await compileManifest(
162
- manifestPath,
163
- dist,
164
- options,
165
- );
166
- } catch (e: any) {
167
- console.error(`Error building ${manifestPath}:`, e.message);
168
- throw e;
169
- }
170
- }));
162
+ await Promise.all(
163
+ manifestFiles.map(async (plugManifestPath) => {
164
+ const manifestPath = plugManifestPath as string;
165
+ try {
166
+ await compileManifest(manifestPath, dist, options);
167
+ } catch (e: any) {
168
+ console.error(`Error building ${manifestPath}:`, e.message);
169
+ throw e;
170
+ }
171
+ }),
172
+ );
171
173
  console.log(`Done building plugs in ${Date.now() - startTime}ms`);
172
174
  building = false;
173
175
  }
@@ -181,21 +183,21 @@ export function patchBundledJS(code: string): string {
181
183
  }
182
184
 
183
185
  export async function plugCompileCommand(
184
- { dist, debug, info }: {
186
+ {
187
+ dist,
188
+ debug,
189
+ info,
190
+ }: {
185
191
  dist: string;
186
192
  debug: boolean;
187
193
  info: boolean;
188
194
  },
189
195
  ...manifestPaths: string[]
190
196
  ) {
191
- await compileManifests(
192
- manifestPaths,
193
- dist,
194
- {
195
- debug: debug,
196
- info: info,
197
- },
198
- );
199
- esbuild.stop();
197
+ await compileManifests(manifestPaths, dist, {
198
+ debug: debug,
199
+ info: info,
200
+ });
201
+ await esbuild.stop();
200
202
  process.exit(0);
201
203
  }
@@ -3,38 +3,38 @@ import type { Manifest } from "@silverbulletmd/silverbullet/type/manifest";
3
3
  // Messages received from the worker
4
4
  export type ControllerMessage =
5
5
  | {
6
- // Parsed manifest when worker is initialized
7
- type: "manifest";
8
- manifest: Manifest;
9
- }
6
+ // Parsed manifest when worker is initialized
7
+ type: "manifest";
8
+ manifest: Manifest;
9
+ }
10
10
  | {
11
- // Function invocation result
12
- type: "invr";
13
- id: number;
14
- error?: string;
15
- result?: any;
16
- }
11
+ // Function invocation result
12
+ type: "invr";
13
+ id: number;
14
+ error?: string;
15
+ result?: any;
16
+ }
17
17
  | {
18
- // Syscall
19
- type: "sys";
20
- id: number;
21
- name: string;
22
- args: any[];
23
- };
18
+ // Syscall
19
+ type: "sys";
20
+ id: number;
21
+ name: string;
22
+ args: any[];
23
+ };
24
24
 
25
25
  // Messages received inside the worker
26
26
  export type WorkerMessage =
27
27
  | {
28
- // Function invocation
29
- type: "inv";
30
- id: number;
31
- name: string;
32
- args: any[];
33
- }
28
+ // Function invocation
29
+ type: "inv";
30
+ id: number;
31
+ name: string;
32
+ args: any[];
33
+ }
34
34
  | {
35
- // Syscall result
36
- type: "sysr";
37
- id: number;
38
- result?: any;
39
- error?: any;
40
- };
35
+ // Syscall result
36
+ type: "sysr";
37
+ id: number;
38
+ result?: any;
39
+ error?: any;
40
+ };
@@ -35,12 +35,13 @@ export async function performLocalFetch(
35
35
  ): Promise<ProxyFetchResponse64> {
36
36
  const result = await fetch(
37
37
  url,
38
- req && {
39
- method: req.method,
40
- headers: req.headers,
41
- body: req.base64Body && base64Decode(req.base64Body),
42
- // Casting to any due to TypeScript fetch type limitations
43
- } as any,
38
+ req &&
39
+ ({
40
+ method: req.method,
41
+ headers: req.headers,
42
+ body: req.base64Body && base64Decode(req.base64Body),
43
+ // Casting to any due to TypeScript fetch type limitations
44
+ } as any),
44
45
  );
45
46
  return {
46
47
  ok: result.ok,
@@ -22,8 +22,7 @@ export class WorkerSandbox<HookT> implements Sandbox<HookT> {
22
22
  readonly plug: Plug<HookT>,
23
23
  public workerUrl: URL,
24
24
  private workerOptions = {},
25
- ) {
26
- }
25
+ ) {}
27
26
 
28
27
  /**
29
28
  * Should only invoked lazily (either by invoke, or by a ManifestCache to load the manifest)
@@ -43,7 +42,7 @@ export class WorkerSandbox<HookT> implements Sandbox<HookT> {
43
42
  return race([
44
43
  // We're adding a timeout of 5s here to handle the case where a plug blows up during initialization
45
44
  timeout(5000).catch((_) =>
46
- Promise.reject(new Error("Plug timed out during creation"))
45
+ Promise.reject(new Error("Plug timed out during creation")),
47
46
  ),
48
47
  new Promise((resolve) => {
49
48
  this.worker!.onmessage = (ev) => {
@@ -54,13 +53,13 @@ export class WorkerSandbox<HookT> implements Sandbox<HookT> {
54
53
 
55
54
  // Set assets in the plug
56
55
  this.plug.assets = new AssetBundle(
57
- this.manifest?.assets ? this.manifest.assets as AssetJson : {},
56
+ this.manifest?.assets ? (this.manifest.assets as AssetJson) : {},
58
57
  );
59
58
 
60
59
  return resolve();
61
60
  }
62
61
 
63
- this.onMessage(ev.data);
62
+ void this.onMessage(ev.data);
64
63
  };
65
64
  }),
66
65
  ]);
@@ -76,18 +75,20 @@ export class WorkerSandbox<HookT> implements Sandbox<HookT> {
76
75
  try {
77
76
  const result = await this.plug.syscall(data.name!, data.args!);
78
77
 
79
- this.worker && this.worker!.postMessage({
80
- type: "sysr",
81
- id: data.id,
82
- result: result,
83
- } as WorkerMessage);
78
+ this.worker &&
79
+ this.worker!.postMessage({
80
+ type: "sysr",
81
+ id: data.id,
82
+ result: result,
83
+ } as WorkerMessage);
84
84
  } catch (e: any) {
85
85
  // console.error("Syscall fail", e);
86
- this.worker && this.worker!.postMessage({
87
- type: "sysr",
88
- id: data.id,
89
- error: e.message,
90
- } as WorkerMessage);
86
+ this.worker &&
87
+ this.worker!.postMessage({
88
+ type: "sysr",
89
+ id: data.id,
90
+ error: e.message,
91
+ } as WorkerMessage);
91
92
  }
92
93
  break;
93
94
  case "invr": {
@@ -4,9 +4,7 @@ import type { FileMeta } from "../../../plug-api/types/index.ts";
4
4
  export default function assetSyscalls(system: System<any>): SysCallMapping {
5
5
  return {
6
6
  "asset.readAsset": (_ctx, plugName: string, name: string): string => {
7
- return system.loadedPlugs.get(plugName)!.assets!.readFileAsDataUrl(
8
- name,
9
- );
7
+ return system.loadedPlugs.get(plugName)!.assets!.readFileAsDataUrl(name);
10
8
  },
11
9
  "asset.listFiles": (_ctx, plugName: string): FileMeta[] => {
12
10
  const assets = system.loadedPlugs.get(plugName)!.assets!;
@@ -12,9 +12,7 @@ export function codeWidgetSyscalls(
12
12
  body: string,
13
13
  pageName: string,
14
14
  ): Promise<CodeWidgetContent | null> => {
15
- const langCallback = codeWidgetHook.codeWidgetCallbacks.get(
16
- lang,
17
- );
15
+ const langCallback = codeWidgetHook.codeWidgetCallbacks.get(lang);
18
16
  if (!langCallback) {
19
17
  throw new Error(`Code widget ${lang} not found`);
20
18
  }
@@ -23,11 +23,7 @@ export function configSyscalls(config: Config): SysCallMapping {
23
23
  keyOrValues = await luaValueToJS(keyOrValues, LuaStackFrame.lostFrame);
24
24
  config.set(keyOrValues as any, value);
25
25
  },
26
- "config.insert": (
27
- _ctx,
28
- key: string | string[],
29
- value: any,
30
- ) => {
26
+ "config.insert": (_ctx, key: string | string[], value: any) => {
31
27
  config.insert(key, value);
32
28
  },
33
29
  "config.has": (_ctx, path: string) => {
@@ -61,7 +61,7 @@ export function dataStoreReadSyscalls(
61
61
  }
62
62
  }
63
63
  return (await queryLua<any>(ds.kv, prefix, query, env, sf)).map((item) =>
64
- luaValueToJS(item, sf)
64
+ luaValueToJS(item, sf),
65
65
  );
66
66
  },
67
67
  };