@silverbulletmd/silverbullet 2.9.0 → 2.10.0

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 (63) hide show
  1. package/README.md +36 -23
  2. package/client/plugos/hooks/syscall.ts +24 -10
  3. package/client/plugos/syscalls/asset.ts +61 -23
  4. package/client/plugos/syscalls/clientStore.ts +32 -6
  5. package/client/plugos/syscalls/client_code_widget.ts +9 -4
  6. package/client/plugos/syscalls/code_widget.ts +26 -11
  7. package/client/plugos/syscalls/config.ts +146 -30
  8. package/client/plugos/syscalls/datastore.ts +146 -40
  9. package/client/plugos/syscalls/editor.ts +1432 -711
  10. package/client/plugos/syscalls/event.ts +46 -13
  11. package/client/plugos/syscalls/fetch.ts +123 -82
  12. package/client/plugos/syscalls/index.ts +242 -116
  13. package/client/plugos/syscalls/jsonschema.ts +107 -8
  14. package/client/plugos/syscalls/language.ts +38 -12
  15. package/client/plugos/syscalls/markdown.ts +166 -50
  16. package/client/plugos/syscalls/mq.ts +93 -20
  17. package/client/plugos/syscalls/schema_introspection.ts +33 -0
  18. package/client/plugos/syscalls/service_registry.ts +74 -20
  19. package/client/plugos/syscalls/shell.ts +51 -20
  20. package/client/plugos/syscalls/space.ts +169 -113
  21. package/client/plugos/syscalls/sync.ts +50 -19
  22. package/client/plugos/syscalls/system.ts +236 -139
  23. package/client/plugos/system.ts +21 -5
  24. package/client/space_lua/api_documentation.ts +107 -0
  25. package/client/space_lua/ast.ts +13 -0
  26. package/client/space_lua/eval.ts +12 -4
  27. package/client/space_lua/parse.ts +243 -108
  28. package/client/space_lua/pretty_print.ts +128 -54
  29. package/client/space_lua/query_collection.ts +4 -4
  30. package/client/space_lua/render_widget.ts +156 -0
  31. package/client/space_lua/runtime.ts +83 -22
  32. package/client/space_lua/stdlib/crypto.ts +8 -3
  33. package/client/space_lua/stdlib/encoding.ts +27 -9
  34. package/client/space_lua/stdlib/js.ts +137 -22
  35. package/client/space_lua/stdlib/load.ts +24 -15
  36. package/client/space_lua/stdlib/math.ts +323 -118
  37. package/client/space_lua/stdlib/net.ts +57 -9
  38. package/client/space_lua/stdlib/os.ts +111 -44
  39. package/client/space_lua/stdlib/space_lua.ts +344 -20
  40. package/client/space_lua/stdlib/string.ts +282 -104
  41. package/client/space_lua/stdlib/string_pack.ts +58 -19
  42. package/client/space_lua/stdlib/table.ts +195 -40
  43. package/client/space_lua/stdlib.ts +335 -93
  44. package/client/space_lua/syscalls.ts +270 -0
  45. package/dist/plug-compile.js +1 -1
  46. package/package.json +3 -3
  47. package/plug-api/lib/ref.ts +96 -0
  48. package/plug-api/lib/shortcut.ts +2 -1
  49. package/plug-api/syscalls/config.ts +5 -3
  50. package/plug-api/syscalls/editor.ts +16 -0
  51. package/plug-api/syscalls/index.ts +17 -1
  52. package/plug-api/syscalls/jsonschema.ts +9 -0
  53. package/plug-api/syscalls/lua.ts +7 -0
  54. package/plug-api/syscalls/shell.ts +0 -1
  55. package/plug-api/syscalls/system.ts +7 -0
  56. package/plug-api/system_mock.ts +2 -2
  57. package/plug-api/types/index.ts +52 -1
  58. package/plug-api/types/manifest.ts +22 -4
  59. package/plug-api/ui/cx.ts +1 -3
  60. package/plug-api/ui/index.ts +3 -0
  61. package/plug-api/ui/panel_styles.ts +4 -3
  62. package/plug-api/ui/slugify.ts +44 -0
  63. package/client/plugos/syscalls/lua.ts +0 -81
@@ -9,25 +9,58 @@ export function eventSyscalls(
9
9
  client: Client,
10
10
  ): SysCallMapping {
11
11
  return {
12
- "event.dispatch": (_ctx, eventName: string, data: any) => {
13
- return eventHook.dispatchEvent(eventName, data);
12
+ "event.dispatch": {
13
+ callback: (_ctx, eventName: string, data: any) => {
14
+ return eventHook.dispatchEvent(eventName, data);
15
+ },
16
+ description:
17
+ "Dispatches an event and collects responses from its listeners.",
18
+ parameters: [
19
+ { name: "eventName", type: "string", description: "Event name." },
20
+ { name: "data", description: "Event payload." },
21
+ ],
22
+ returns: [{ type: "table", description: "Listener responses." }],
23
+ examples: [
24
+ {
25
+ code: 'local responses = event.dispatch("data.request", {id = 123})',
26
+ },
27
+ ],
14
28
  },
15
- "event.listEvents": () => {
16
- return eventHook.listEvents();
29
+ "event.listEvents": {
30
+ callback: () => {
31
+ return eventHook.listEvents();
32
+ },
33
+ description: "Lists all event names that currently have listeners.",
34
+ returns: [{ type: "table", description: "Registered event names." }],
17
35
  },
18
36
  /**
19
37
  * Define a Lua event listener
20
38
  */
21
- "event.listen": (_ctx, def: EventSubscription) => {
22
- // console.log("Registering Lua event listener: ", def.name);
23
- client.config.insert(
24
- ["eventListeners", def.name],
25
- async (...args: any[]) => {
26
- // Convert return value to JS
27
- const val = await def.run(...args);
28
- return luaValueToJS(val, LuaStackFrame.lostFrame);
39
+ "event.listen": {
40
+ callback: (_ctx, def: EventSubscription) => {
41
+ // console.log("Registering Lua event listener: ", def.name);
42
+ client.config.insert(
43
+ ["eventListeners", def.name],
44
+ async (...args: any[]) => {
45
+ // Convert return value to JS
46
+ const val = await def.run(...args);
47
+ return luaValueToJS(val, LuaStackFrame.lostFrame);
48
+ },
49
+ );
50
+ },
51
+ description: "Registers a Space Lua listener on the event bus.",
52
+ parameters: [
53
+ {
54
+ name: "listener",
55
+ type: "table",
56
+ description: "Listener definition with name and run callback.",
57
+ },
58
+ ],
59
+ examples: [
60
+ {
61
+ code: 'event.listen { name = "my-event", run = function(e) print(e.data) end }',
29
62
  },
30
- );
63
+ ],
31
64
  },
32
65
  };
33
66
  }
@@ -15,91 +15,132 @@ import { fsEndpoint } from "../../spaces/constants.ts";
15
15
  export function sandboxFetchSyscalls(client: Client): SysCallMapping {
16
16
  return {
17
17
  // For use in Lua
18
- "http.request": async (
19
- _ctx,
20
- url: string,
21
- options: ProxyFetchRequest = {},
22
- ): Promise<ProxyFetchResponse> => {
23
- console.warn("Deprecated: use net.proxyFetch() instead");
24
- // JSONify any non-serializable body
25
- if (
26
- options?.body &&
27
- typeof options.body !== "string" &&
28
- !(options.body instanceof Uint8Array)
29
- ) {
30
- options.body = JSON.stringify(options.body);
31
- }
32
- const fetchOptions = options
33
- ? {
34
- method: options.method,
35
- headers: {} as Record<string, string>,
36
- body: options.body,
37
- }
38
- : {};
18
+ "http.request": {
19
+ callback: async (
20
+ _ctx,
21
+ url: string,
22
+ options: ProxyFetchRequest = {},
23
+ ): Promise<ProxyFetchResponse> => {
24
+ console.warn("Deprecated: use net.proxyFetch() instead");
25
+ // JSONify any non-serializable body
26
+ if (
27
+ options?.body &&
28
+ typeof options.body !== "string" &&
29
+ !(options.body instanceof Uint8Array)
30
+ ) {
31
+ options.body = JSON.stringify(options.body);
32
+ }
33
+ const fetchOptions = options
34
+ ? {
35
+ method: options.method,
36
+ headers: {} as Record<string, string>,
37
+ body: options.body,
38
+ }
39
+ : {};
39
40
 
40
- fetchOptions.headers = buildProxyHeaders(options?.headers);
41
+ fetchOptions.headers = buildProxyHeaders(options?.headers);
41
42
 
42
- const resp = await client.httpSpacePrimitives.authenticatedFetch(
43
- buildProxyUrl(client, url),
44
- fetchOptions,
45
- );
46
- // Do sensible things with the body based on the content type
47
- // Read as ArrayBuffer first to safely handle empty responses (e.g.
48
- // PUT/DELETE returning 204 with Content-Type: application/json).
49
- // resp.arrayBuffer() never throws on an empty body, whereas
50
- // resp.json() would throw a SyntaxError.
51
- const rawBytes = new Uint8Array(await resp.arrayBuffer());
52
- let body: any;
53
- const contentTypeHeader =
54
- options.responseEncoding ||
55
- resp.headers.get("x-proxy-header-content-type");
56
- const statusCode = +(resp.headers.get("x-proxy-status-code") || "200");
57
- if (rawBytes.length === 0) {
58
- body = null;
59
- } else if (contentTypeHeader?.startsWith("application/json")) {
60
- body = JSON.parse(new TextDecoder().decode(rawBytes));
61
- } else if (
62
- contentTypeHeader?.startsWith("application/xml") ||
63
- contentTypeHeader?.startsWith("text/")
64
- ) {
65
- body = new TextDecoder().decode(rawBytes);
66
- } else {
67
- body = rawBytes;
68
- }
69
- return {
70
- ok: resp.ok,
71
- status: statusCode,
72
- headers: extractProxyHeaders(resp.headers),
73
- body: body,
74
- };
43
+ const resp = await client.httpSpacePrimitives.authenticatedFetch(
44
+ buildProxyUrl(client, url),
45
+ fetchOptions,
46
+ );
47
+ // Do sensible things with the body based on the content type
48
+ // Read as ArrayBuffer first to safely handle empty responses (e.g.
49
+ // PUT/DELETE returning 204 with Content-Type: application/json).
50
+ // resp.arrayBuffer() never throws on an empty body, whereas
51
+ // resp.json() would throw a SyntaxError.
52
+ const rawBytes = new Uint8Array(await resp.arrayBuffer());
53
+ let body: any;
54
+ const contentTypeHeader =
55
+ options.responseEncoding ||
56
+ resp.headers.get("x-proxy-header-content-type");
57
+ const statusCode = +(resp.headers.get("x-proxy-status-code") || "200");
58
+ if (rawBytes.length === 0) {
59
+ body = null;
60
+ } else if (contentTypeHeader?.startsWith("application/json")) {
61
+ body = JSON.parse(new TextDecoder().decode(rawBytes));
62
+ } else if (
63
+ contentTypeHeader?.startsWith("application/xml") ||
64
+ contentTypeHeader?.startsWith("text/")
65
+ ) {
66
+ body = new TextDecoder().decode(rawBytes);
67
+ } else {
68
+ body = rawBytes;
69
+ }
70
+ return {
71
+ ok: resp.ok,
72
+ status: statusCode,
73
+ headers: extractProxyHeaders(resp.headers),
74
+ body: body,
75
+ };
76
+ },
77
+ description:
78
+ "Performs an authenticated HTTP request through the server proxy.",
79
+ parameters: [
80
+ { name: "url", type: "string", description: "Target URL." },
81
+ {
82
+ name: "options",
83
+ type: "table",
84
+ description: "Method, headers, body, and response encoding.",
85
+ optional: true,
86
+ },
87
+ ],
88
+ returns: [
89
+ {
90
+ type: "table",
91
+ description: "Status, headers, and decoded response body.",
92
+ },
93
+ ],
94
+ deprecated: "Use net.proxyFetch instead.",
95
+ see: "API/net#net.proxyFetch(url, options?)",
75
96
  },
76
- "sandboxFetch.fetch": async (
77
- _ctx,
78
- url: string,
79
- options?: ProxyFetchRequest64,
80
- ): Promise<ProxyFetchResponse64> => {
81
- // console.log("Got sandbox fetch ", url, op);
82
- const fetchOptions = options
83
- ? {
84
- method: options.method,
85
- headers: options.headers,
86
- body: options.base64Body && base64Decode(options.base64Body),
87
- }
88
- : {};
89
- fetchOptions.headers = buildProxyHeaders(options?.headers);
90
- const resp = await client.httpSpacePrimitives.authenticatedFetch(
91
- buildProxyUrl(client, url),
92
- // Casting to any due to TypeScript fetch type limitations
93
- fetchOptions as any,
94
- );
95
- const statusCode = +(resp.headers.get("x-proxy-status-code") || "200");
96
- const body = await resp.arrayBuffer();
97
- return {
98
- ok: resp.ok,
99
- status: statusCode,
100
- headers: extractProxyHeaders(resp.headers),
101
- base64Body: base64Encode(new Uint8Array(body)),
102
- };
97
+ "sandboxFetch.fetch": {
98
+ callback: async (
99
+ _ctx,
100
+ url: string,
101
+ options?: ProxyFetchRequest64,
102
+ ): Promise<ProxyFetchResponse64> => {
103
+ // console.log("Got sandbox fetch ", url, op);
104
+ const fetchOptions = options
105
+ ? {
106
+ method: options.method,
107
+ headers: options.headers,
108
+ body: options.base64Body && base64Decode(options.base64Body),
109
+ }
110
+ : {};
111
+ fetchOptions.headers = buildProxyHeaders(options?.headers);
112
+ const resp = await client.httpSpacePrimitives.authenticatedFetch(
113
+ buildProxyUrl(client, url),
114
+ // Casting to any due to TypeScript fetch type limitations
115
+ fetchOptions as any,
116
+ );
117
+ const statusCode = +(resp.headers.get("x-proxy-status-code") || "200");
118
+ const body = await resp.arrayBuffer();
119
+ return {
120
+ ok: resp.ok,
121
+ status: statusCode,
122
+ headers: extractProxyHeaders(resp.headers),
123
+ base64Body: base64Encode(new Uint8Array(body)),
124
+ };
125
+ },
126
+ description:
127
+ "Performs an authenticated proxied fetch for a plug sandbox.",
128
+ parameters: [
129
+ { name: "url", type: "string", description: "Target URL." },
130
+ {
131
+ name: "options",
132
+ type: "table",
133
+ description: "Method, headers, and base64-encoded body.",
134
+ optional: true,
135
+ },
136
+ ],
137
+ returns: [
138
+ {
139
+ type: "table",
140
+ description: "Status, headers, and base64-encoded response body.",
141
+ },
142
+ ],
143
+ see: "API/http",
103
144
  },
104
145
  };
105
146
  }