@silverbulletmd/silverbullet 2.9.0 → 2.11.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 (123) hide show
  1. package/README.md +38 -25
  2. package/client/asset_bundle/bundle.ts +0 -1
  3. package/client/config.ts +343 -0
  4. package/client/markdown_parser/constants.ts +3 -1
  5. package/client/plugos/hooks/command.ts +0 -5
  6. package/client/plugos/hooks/event.ts +0 -6
  7. package/client/plugos/hooks/mq.ts +0 -3
  8. package/client/plugos/hooks/slash_command.ts +1 -7
  9. package/client/plugos/hooks/syscall.ts +24 -14
  10. package/client/plugos/manifest_cache.ts +0 -32
  11. package/client/plugos/plug.ts +0 -3
  12. package/client/plugos/plug_compile.ts +3 -13
  13. package/client/plugos/sandboxes/worker_sandbox.ts +19 -9
  14. package/client/plugos/syscalls/asset.ts +61 -23
  15. package/client/plugos/syscalls/clientStore.ts +32 -6
  16. package/client/plugos/syscalls/client_code_widget.ts +9 -4
  17. package/client/plugos/syscalls/code_widget.ts +26 -11
  18. package/client/plugos/syscalls/config.ts +146 -30
  19. package/client/plugos/syscalls/datastore.ts +146 -40
  20. package/client/plugos/syscalls/editor.ts +1518 -722
  21. package/client/plugos/syscalls/event.ts +44 -13
  22. package/client/plugos/syscalls/fetch.ts +120 -83
  23. package/client/plugos/syscalls/icon.ts +46 -0
  24. package/client/plugos/syscalls/index.ts +267 -121
  25. package/client/plugos/syscalls/jsonschema.ts +107 -9
  26. package/client/plugos/syscalls/language.ts +38 -12
  27. package/client/plugos/syscalls/markdown.ts +166 -50
  28. package/client/plugos/syscalls/mq.ts +92 -20
  29. package/client/plugos/syscalls/navigator.ts +143 -0
  30. package/client/plugos/syscalls/schema_introspection.ts +33 -0
  31. package/client/plugos/syscalls/search.ts +44 -0
  32. package/client/plugos/syscalls/service_registry.ts +74 -20
  33. package/client/plugos/syscalls/shell.ts +51 -21
  34. package/client/plugos/syscalls/space.ts +412 -113
  35. package/client/plugos/syscalls/sync.ts +103 -20
  36. package/client/plugos/syscalls/system.ts +274 -139
  37. package/client/plugos/system.ts +28 -10
  38. package/client/plugos/worker_runtime.ts +0 -2
  39. package/client/space_lua/aggregates.ts +0 -16
  40. package/client/space_lua/api_documentation.ts +107 -0
  41. package/client/space_lua/ast.ts +13 -5
  42. package/client/space_lua/ast_narrow.ts +0 -5
  43. package/client/space_lua/budget.ts +113 -0
  44. package/client/space_lua/budget_ui.ts +49 -0
  45. package/client/space_lua/eval.ts +125 -92
  46. package/client/space_lua/labels.ts +0 -4
  47. package/client/space_lua/numeric.ts +0 -5
  48. package/client/space_lua/parse.ts +243 -125
  49. package/client/space_lua/pretty_print.ts +128 -54
  50. package/client/space_lua/quarantine.ts +127 -0
  51. package/client/space_lua/query_collection.ts +7 -51
  52. package/client/space_lua/query_env.ts +0 -2
  53. package/client/space_lua/render_lua_markdown.ts +2 -7
  54. package/client/space_lua/render_widget.ts +173 -0
  55. package/client/space_lua/runtime.ts +133 -92
  56. package/client/space_lua/stdlib/crypto.ts +8 -3
  57. package/client/space_lua/stdlib/encoding.ts +27 -9
  58. package/client/space_lua/stdlib/format.ts +0 -12
  59. package/client/space_lua/stdlib/js.ts +136 -23
  60. package/client/space_lua/stdlib/load.ts +24 -16
  61. package/client/space_lua/stdlib/math.ts +331 -133
  62. package/client/space_lua/stdlib/net.ts +57 -13
  63. package/client/space_lua/stdlib/os.ts +111 -54
  64. package/client/space_lua/stdlib/pattern.ts +10 -15
  65. package/client/space_lua/stdlib/space_lua.ts +344 -21
  66. package/client/space_lua/stdlib/string.ts +282 -104
  67. package/client/space_lua/stdlib/string_pack.ts +58 -22
  68. package/client/space_lua/stdlib/table.ts +195 -45
  69. package/client/space_lua/stdlib.ts +354 -125
  70. package/client/space_lua/syscalls.ts +270 -0
  71. package/client/space_lua/tonumber.ts +0 -9
  72. package/dist/plug-compile.js +2 -3
  73. package/package.json +15 -5
  74. package/plug-api/lib/async.ts +1 -6
  75. package/plug-api/lib/collation.ts +22 -0
  76. package/plug-api/lib/crypto.ts +16 -15
  77. package/plug-api/lib/dates.ts +33 -0
  78. package/plug-api/lib/fuzzy.ts +282 -0
  79. package/plug-api/lib/json.ts +0 -6
  80. package/plug-api/lib/limited_map.ts +0 -2
  81. package/plug-api/lib/link_write.ts +27 -0
  82. package/plug-api/{ui → lib}/panel_styles.ts +4 -3
  83. package/plug-api/lib/ref.ts +124 -5
  84. package/plug-api/lib/resolve.ts +0 -1
  85. package/plug-api/lib/resolve_path.ts +290 -0
  86. package/plug-api/lib/shortcut.ts +17 -1
  87. package/plug-api/lib/tags.ts +0 -3
  88. package/plug-api/lib/transclusion.ts +28 -1
  89. package/plug-api/lib/tree.ts +0 -5
  90. package/plug-api/lib/yaml.ts +3 -42
  91. package/plug-api/syscall.ts +1 -5
  92. package/plug-api/syscalls/config.ts +7 -5
  93. package/plug-api/syscalls/editor.ts +70 -208
  94. package/plug-api/syscalls/icon.ts +18 -0
  95. package/plug-api/syscalls/index.ts +39 -5
  96. package/plug-api/syscalls/jsonschema.ts +9 -0
  97. package/plug-api/syscalls/lua.ts +7 -0
  98. package/plug-api/syscalls/search.ts +11 -0
  99. package/plug-api/syscalls/shell.ts +0 -1
  100. package/plug-api/syscalls/space.ts +122 -5
  101. package/plug-api/syscalls/sync.ts +23 -2
  102. package/plug-api/syscalls/system.ts +53 -0
  103. package/plug-api/syscalls.ts +2 -0
  104. package/plug-api/system_mock.ts +15 -2
  105. package/plug-api/types/client.ts +4 -3
  106. package/plug-api/types/datastore.ts +11 -2
  107. package/plug-api/types/index.ts +62 -1
  108. package/plug-api/types/manifest.ts +22 -4
  109. package/plug-api/types/profile.ts +13 -0
  110. package/plug-api/types/revisions.ts +67 -0
  111. package/plug-api/ui/cx.ts +1 -3
  112. package/plug-api/ui/description.ts +64 -0
  113. package/plug-api/ui/hover.ts +69 -0
  114. package/plug-api/ui/index.ts +61 -2
  115. package/plug-api/ui/scroll.ts +30 -0
  116. package/plug-api/ui/slugify.ts +44 -0
  117. package/plug-api/ui/tree_model.ts +263 -0
  118. package/plug-api/ui/tree_types.ts +66 -0
  119. package/plug-api/ui/use_fit_collapse.ts +67 -0
  120. package/plugs/builtin_plugs.ts +0 -1
  121. package/plugs/index/types.ts +9 -0
  122. package/client/plugos/syscalls/lua.ts +0 -81
  123. package/plug-api/lib/memory_cache.ts +0 -21
@@ -18,31 +18,36 @@ function untagNumber(x: any): number {
18
18
  }
19
19
 
20
20
  export const mathApi = new LuaTable({
21
- // math constants
22
21
  huge: 1 / 0,
23
22
  pi: Math.PI,
24
23
 
25
24
  // math.type(x) => "integer" | "float" | nil
26
- type: new LuaBuiltinFunction((_sf, x?: any) => {
27
- if (x === undefined) {
28
- throw new LuaRuntimeError(
29
- "bad argument #1 to 'math.type' (value expected)",
30
- _sf,
31
- );
32
- }
33
- if (isTaggedFloat(x)) {
34
- return "float";
35
- }
36
- if (typeof x === "number") {
37
- if (!Number.isFinite(x) || isNegativeZero(x)) {
25
+ type: new LuaBuiltinFunction({
26
+ callback: (_sf, x?: any) => {
27
+ if (x === undefined) {
28
+ throw new LuaRuntimeError(
29
+ "bad argument #1 to 'math.type' (value expected)",
30
+ _sf,
31
+ );
32
+ }
33
+ if (isTaggedFloat(x)) {
38
34
  return "float";
39
35
  }
40
- return Number.isInteger(x) ? "integer" : "float";
41
- }
42
- if (typeof x === "bigint") {
43
- return "integer";
44
- }
45
- return null;
36
+ if (typeof x === "number") {
37
+ if (!Number.isFinite(x) || isNegativeZero(x)) {
38
+ return "float";
39
+ }
40
+ return Number.isInteger(x) ? "integer" : "float";
41
+ }
42
+ if (typeof x === "bigint") {
43
+ return "integer";
44
+ }
45
+ return null;
46
+ },
47
+ description:
48
+ "Returns `integer` or `float` for a number, or `nil` for other values.",
49
+ parameters: [{ name: "x", description: "Value to inspect." }],
50
+ returns: [{ type: "string|nil", description: "Numeric subtype or `nil`." }],
46
51
  }),
47
52
 
48
53
  /**
@@ -50,21 +55,29 @@ export const mathApi = new LuaTable({
50
55
  * with that value. Otherwise returns nil.
51
56
  * Strings are NOT accepted — only Lua number values.
52
57
  */
53
- tointeger: new LuaBuiltinFunction((_sf, x?: any) => {
54
- if (typeof x === "number") {
55
- return Number.isInteger(x) && Number.isFinite(x) ? x : null;
56
- }
57
- if (isTaggedFloat(x)) {
58
- const n = x.value;
59
- return Number.isInteger(n) && Number.isFinite(n) ? n : null;
60
- }
61
- if (typeof x === "string") {
62
- const n = untagNumber(x); // Number(x) coerces the string
63
- if (Number.isNaN(n) || !Number.isFinite(n) || !Number.isInteger(n))
64
- return null;
65
- return n;
66
- }
67
- return null;
58
+ tointeger: new LuaBuiltinFunction({
59
+ callback: (_sf, x?: any) => {
60
+ if (typeof x === "number") {
61
+ return Number.isInteger(x) && Number.isFinite(x) ? x : null;
62
+ }
63
+ if (isTaggedFloat(x)) {
64
+ const n = x.value;
65
+ return Number.isInteger(n) && Number.isFinite(n) ? n : null;
66
+ }
67
+ if (typeof x === "string") {
68
+ const n = untagNumber(x); // Number(x) coerces the string
69
+ if (Number.isNaN(n) || !Number.isFinite(n) || !Number.isInteger(n))
70
+ return null;
71
+ return n;
72
+ }
73
+ return null;
74
+ },
75
+ description:
76
+ "Converts a value to an integer when it has an exact finite integral representation.",
77
+ parameters: [{ name: "x", description: "Value to convert." }],
78
+ returns: [
79
+ { type: "integer|nil", description: "Converted integer or `nil`." },
80
+ ],
68
81
  }),
69
82
 
70
83
  /**
@@ -76,122 +89,299 @@ export const mathApi = new LuaTable({
76
89
  * math.random(1,n). The call math.random(0) produces an integer
77
90
  * with all bits (pseudo)random.
78
91
  */
79
- random: new LuaBuiltinFunction((_sf, m?: number, n?: number) => {
80
- if (m !== undefined) m = untagNumber(m);
81
- if (n !== undefined) n = untagNumber(n);
82
- try {
83
- return prng.random(m, n);
84
- } catch (e: any) {
85
- throw new LuaRuntimeError(e.message, _sf);
86
- }
92
+ random: new LuaBuiltinFunction({
93
+ callback: (_sf, m?: number, n?: number) => {
94
+ if (m !== undefined) m = untagNumber(m);
95
+ if (n !== undefined) n = untagNumber(n);
96
+ try {
97
+ return prng.random(m, n);
98
+ } catch (e: any) {
99
+ throw new LuaRuntimeError(e.message, _sf);
100
+ }
101
+ },
102
+ description:
103
+ "Returns a pseudo-random float or an integer in a requested inclusive range.",
104
+ signatures: [
105
+ "math.random(): number",
106
+ "math.random(n): integer",
107
+ "math.random(m, n): integer",
108
+ ],
109
+ parameters: [
110
+ { name: "m", type: "integer", optional: true },
111
+ { name: "n", type: "integer", optional: true },
112
+ ],
113
+ returns: [{ type: "number", description: "Pseudo-random result." }],
114
+ examples: [
115
+ {
116
+ code: "print(math.random())\nprint(math.random(10))\nprint(math.random(5, 10))",
117
+ },
118
+ ],
87
119
  }),
88
120
  /**
89
121
  * Seeds the pseudo-random generator. With no arguments, uses a
90
122
  * time-based seed. Returns the two seed integers used (Lua 5.4 contract).
91
123
  */
92
- randomseed: new LuaBuiltinFunction((_sf, x?: number, y?: number) => {
93
- if (x !== undefined) x = untagNumber(x);
94
- if (y !== undefined) y = untagNumber(y);
95
- const [s1, s2] = prng.randomseed(x, y);
96
- return new LuaMultiRes([s1, s2]);
97
- }),
98
-
99
- // Basic functions
100
- abs: new LuaBuiltinFunction((_sf, x: number) => Math.abs(untagNumber(x))),
101
- ceil: new LuaBuiltinFunction((_sf, x: number) => Math.ceil(untagNumber(x))),
102
- floor: new LuaBuiltinFunction((_sf, x: number) => Math.floor(untagNumber(x))),
103
- max: new LuaBuiltinFunction((_sf, ...args: number[]) =>
104
- Math.max(...args.map(untagNumber)),
105
- ),
106
- min: new LuaBuiltinFunction((_sf, ...args: number[]) =>
107
- Math.min(...args.map(untagNumber)),
108
- ),
109
-
110
- // Rounding and remainder
111
- fmod: new LuaBuiltinFunction(
112
- (_sf, x: number, y: number) => untagNumber(x) % untagNumber(y),
113
- ),
114
- modf: new LuaBuiltinFunction((_sf, x: number) => {
115
- const xn = untagNumber(x);
116
- const int = Math.trunc(xn);
117
- // Guarantee that the `frac` part is always Lua float
118
- const frac = makeLuaFloat(xn - int);
119
- return new LuaMultiRes([int, frac]);
124
+ randomseed: new LuaBuiltinFunction({
125
+ callback: (_sf, x?: number, y?: number) => {
126
+ if (x !== undefined) x = untagNumber(x);
127
+ if (y !== undefined) y = untagNumber(y);
128
+ const [s1, s2] = prng.randomseed(x, y);
129
+ return new LuaMultiRes([s1, s2]);
130
+ },
131
+ description:
132
+ "Seeds the pseudo-random generator and returns the two seeds used.",
133
+ signatures: [
134
+ "math.randomseed(): integer, integer",
135
+ "math.randomseed(x, y): integer, integer",
136
+ ],
137
+ parameters: [
138
+ { name: "x", type: "integer", optional: true },
139
+ { name: "y", type: "integer", optional: true },
140
+ ],
141
+ returns: [
142
+ { type: "integer", description: "First seed." },
143
+ { type: "integer", description: "Second seed." },
144
+ ],
145
+ }),
146
+
147
+ abs: new LuaBuiltinFunction({
148
+ callback: (_sf, x: number) => Math.abs(untagNumber(x)),
149
+ description: "Returns the absolute value of `x`.",
150
+ parameters: [{ name: "x", type: "number" }],
151
+ returns: [{ type: "number" }],
152
+ }),
153
+ ceil: new LuaBuiltinFunction({
154
+ callback: (_sf, x: number) => Math.ceil(untagNumber(x)),
155
+ description: "Returns the smallest integer greater than or equal to `x`.",
156
+ parameters: [{ name: "x", type: "number" }],
157
+ returns: [{ type: "integer" }],
158
+ }),
159
+ floor: new LuaBuiltinFunction({
160
+ callback: (_sf, x: number) => Math.floor(untagNumber(x)),
161
+ description: "Returns the largest integer less than or equal to `x`.",
162
+ parameters: [{ name: "x", type: "number" }],
163
+ returns: [{ type: "integer" }],
164
+ }),
165
+ max: new LuaBuiltinFunction({
166
+ callback: (_sf, ...args: number[]) => Math.max(...args.map(untagNumber)),
167
+ description: "Returns the greatest of its arguments.",
168
+ signatures: ["math.max(x, ...): number"],
169
+ returns: [{ type: "number" }],
170
+ }),
171
+ min: new LuaBuiltinFunction({
172
+ callback: (_sf, ...args: number[]) => Math.min(...args.map(untagNumber)),
173
+ description: "Returns the least of its arguments.",
174
+ signatures: ["math.min(x, ...): number"],
175
+ returns: [{ type: "number" }],
176
+ }),
177
+
178
+ fmod: new LuaBuiltinFunction({
179
+ callback: (_sf, x: number, y: number) => untagNumber(x) % untagNumber(y),
180
+ description:
181
+ "Returns the remainder of `x / y` with the quotient rounded toward zero.",
182
+ parameters: [
183
+ { name: "x", type: "number" },
184
+ { name: "y", type: "number" },
185
+ ],
186
+ returns: [{ type: "number" }],
187
+ }),
188
+ modf: new LuaBuiltinFunction({
189
+ callback: (_sf, x: number) => {
190
+ const xn = untagNumber(x);
191
+ const int = Math.trunc(xn);
192
+ // Guarantee that the `frac` part is always Lua float
193
+ const frac = makeLuaFloat(xn - int);
194
+ return new LuaMultiRes([int, frac]);
195
+ },
196
+ description: "Splits `x` into its integral and fractional parts.",
197
+ parameters: [{ name: "x", type: "number" }],
198
+ returns: [
199
+ { type: "integer", description: "Integral part." },
200
+ { type: "float", description: "Fractional part." },
201
+ ],
202
+ examples: [{ code: "local integer, fraction = math.modf(3.14)" }],
120
203
  }),
121
204
 
122
205
  // Returns m and e such that x = m * 2^e, 0.5 <= |m| < 1 (or m=0 when x=0).
123
206
  // e is an integer. Mirrors C99/Lua.
124
207
  // Special cases: frexp(0) = (0, 0); frexp(+-inf/nan) = (x, 0).
125
- frexp: new LuaBuiltinFunction((_sf, x: number) => {
126
- const xn = untagNumber(x);
127
- if (xn === 0 || !Number.isFinite(xn) || Number.isNaN(xn)) {
128
- return new LuaMultiRes([xn, 0]);
129
- }
130
- const abs = Math.abs(xn);
131
- let e = Math.floor(Math.log2(abs)) + 1;
132
- let m = xn / 2 ** e;
133
- if (Math.abs(m) >= 1.0) {
134
- e += 1;
135
- m /= 2;
136
- }
137
- if (Math.abs(m) < 0.5) {
138
- e -= 1;
139
- m *= 2;
140
- }
141
- return new LuaMultiRes([m, e]);
208
+ frexp: new LuaBuiltinFunction({
209
+ callback: (_sf, x: number) => {
210
+ const xn = untagNumber(x);
211
+ if (xn === 0 || !Number.isFinite(xn) || Number.isNaN(xn)) {
212
+ return new LuaMultiRes([xn, 0]);
213
+ }
214
+ const abs = Math.abs(xn);
215
+ let e = Math.floor(Math.log2(abs)) + 1;
216
+ let m = xn / 2 ** e;
217
+ if (Math.abs(m) >= 1.0) {
218
+ e += 1;
219
+ m /= 2;
220
+ }
221
+ if (Math.abs(m) < 0.5) {
222
+ e -= 1;
223
+ m *= 2;
224
+ }
225
+ return new LuaMultiRes([m, e]);
226
+ },
227
+ description:
228
+ "Decomposes `x` into a normalized fraction and a power-of-two exponent.",
229
+ parameters: [{ name: "x", type: "number" }],
230
+ returns: [
231
+ { type: "number", description: "Fraction." },
232
+ { type: "integer", description: "Exponent." },
233
+ ],
142
234
  }),
143
235
 
144
236
  // Returns m * 2^e (the inverse of frexp). Mirrors C99/Lua.
145
- ldexp: new LuaBuiltinFunction(
146
- (_sf, m: number, e: number) => untagNumber(m) * 2 ** untagNumber(e),
147
- ),
148
-
149
- // Power and logarithms
150
- exp: new LuaBuiltinFunction((_sf, x: number) => Math.exp(untagNumber(x))),
151
- log: new LuaBuiltinFunction((_sf, x: number, base?: number) => {
152
- if (base === undefined) {
153
- return Math.log(untagNumber(x));
154
- }
155
- return Math.log(untagNumber(x)) / Math.log(untagNumber(base));
237
+ ldexp: new LuaBuiltinFunction({
238
+ callback: (_sf, m: number, e: number) =>
239
+ untagNumber(m) * 2 ** untagNumber(e),
240
+ description: "Returns `m * 2^e`, the inverse of `math.frexp`.",
241
+ parameters: [
242
+ { name: "m", type: "number" },
243
+ { name: "e", type: "integer" },
244
+ ],
245
+ returns: [{ type: "number" }],
246
+ }),
247
+
248
+ exp: new LuaBuiltinFunction({
249
+ callback: (_sf, x: number) => Math.exp(untagNumber(x)),
250
+ description: "Returns `e` raised to `x`.",
251
+ parameters: [{ name: "x", type: "number" }],
252
+ returns: [{ type: "number" }],
253
+ }),
254
+ log: new LuaBuiltinFunction({
255
+ callback: (_sf, x: number, base?: number) => {
256
+ if (base === undefined) {
257
+ return Math.log(untagNumber(x));
258
+ }
259
+ return Math.log(untagNumber(x)) / Math.log(untagNumber(base));
260
+ },
261
+ description:
262
+ "Returns the logarithm of `x`, using the natural base unless another base is supplied.",
263
+ parameters: [
264
+ { name: "x", type: "number" },
265
+ { name: "base", type: "number", optional: true },
266
+ ],
267
+ returns: [{ type: "number" }],
268
+ examples: [{ code: "print(math.log(100, 10)) -- 2" }],
156
269
  }),
157
270
  // Power function (deprecated in Lua 5.4 but retained for compatibility)
158
- pow: new LuaBuiltinFunction(
159
- (_sf, x: number, y: number) => untagNumber(x) ** untagNumber(y),
160
- ),
161
- sqrt: new LuaBuiltinFunction((_sf, x: number) => Math.sqrt(untagNumber(x))),
162
-
163
- // Trigonometric functions
164
- cos: new LuaBuiltinFunction((_sf, x: number) => Math.cos(untagNumber(x))),
165
- sin: new LuaBuiltinFunction((_sf, x: number) => Math.sin(untagNumber(x))),
166
- tan: new LuaBuiltinFunction((_sf, x: number) => Math.tan(untagNumber(x))),
167
- acos: new LuaBuiltinFunction((_sf, x: number) => Math.acos(untagNumber(x))),
168
- asin: new LuaBuiltinFunction((_sf, x: number) => Math.asin(untagNumber(x))),
169
- atan: new LuaBuiltinFunction((_sf, y: number, x?: number) => {
170
- if (x === undefined) {
171
- return Math.atan(untagNumber(y));
172
- }
173
- return Math.atan2(untagNumber(y), untagNumber(x));
271
+ pow: new LuaBuiltinFunction({
272
+ callback: (_sf, x: number, y: number) => untagNumber(x) ** untagNumber(y),
273
+ description: "Returns `x` raised to the power `y`.",
274
+ parameters: [
275
+ { name: "x", type: "number" },
276
+ { name: "y", type: "number" },
277
+ ],
278
+ returns: [{ type: "number" }],
279
+ deprecated: "Use the `^` operator instead.",
280
+ }),
281
+ sqrt: new LuaBuiltinFunction({
282
+ callback: (_sf, x: number) => Math.sqrt(untagNumber(x)),
283
+ description: "Returns the square root of `x`.",
284
+ parameters: [{ name: "x", type: "number" }],
285
+ returns: [{ type: "number" }],
286
+ }),
287
+
288
+ cos: new LuaBuiltinFunction({
289
+ callback: (_sf, x: number) => Math.cos(untagNumber(x)),
290
+ description: "Returns the cosine of `x` radians.",
291
+ parameters: [{ name: "x", type: "number" }],
292
+ returns: [{ type: "number" }],
293
+ }),
294
+ sin: new LuaBuiltinFunction({
295
+ callback: (_sf, x: number) => Math.sin(untagNumber(x)),
296
+ description: "Returns the sine of `x` radians.",
297
+ parameters: [{ name: "x", type: "number" }],
298
+ returns: [{ type: "number" }],
299
+ }),
300
+ tan: new LuaBuiltinFunction({
301
+ callback: (_sf, x: number) => Math.tan(untagNumber(x)),
302
+ description: "Returns the tangent of `x` radians.",
303
+ parameters: [{ name: "x", type: "number" }],
304
+ returns: [{ type: "number" }],
305
+ }),
306
+ acos: new LuaBuiltinFunction({
307
+ callback: (_sf, x: number) => Math.acos(untagNumber(x)),
308
+ description: "Returns the arc cosine of `x` in radians.",
309
+ parameters: [{ name: "x", type: "number" }],
310
+ returns: [{ type: "number" }],
311
+ }),
312
+ asin: new LuaBuiltinFunction({
313
+ callback: (_sf, x: number) => Math.asin(untagNumber(x)),
314
+ description: "Returns the arc sine of `x` in radians.",
315
+ parameters: [{ name: "x", type: "number" }],
316
+ returns: [{ type: "number" }],
317
+ }),
318
+ atan: new LuaBuiltinFunction({
319
+ callback: (_sf, y: number, x?: number) => {
320
+ if (x === undefined) {
321
+ return Math.atan(untagNumber(y));
322
+ }
323
+ return Math.atan2(untagNumber(y), untagNumber(x));
324
+ },
325
+ description:
326
+ "Returns the arc tangent of `y/x` in radians, using `1` for omitted `x`.",
327
+ parameters: [
328
+ { name: "y", type: "number" },
329
+ { name: "x", type: "number", optional: true },
330
+ ],
331
+ returns: [{ type: "number" }],
174
332
  }),
175
333
 
176
334
  // Hyperbolic functions (deprecated in Lua 5.4 but retained for compatibility)
177
- cosh: new LuaBuiltinFunction((_sf, x: number) => Math.cosh(untagNumber(x))),
178
- sinh: new LuaBuiltinFunction((_sf, x: number) => Math.sinh(untagNumber(x))),
179
- tanh: new LuaBuiltinFunction((_sf, x: number) => Math.tanh(untagNumber(x))),
180
-
181
- // Additional utility
182
- deg: new LuaBuiltinFunction(
183
- (_sf, x: number) => (untagNumber(x) * 180) / Math.PI,
184
- ),
185
- rad: new LuaBuiltinFunction(
186
- (_sf, x: number) => (untagNumber(x) * Math.PI) / 180,
187
- ),
188
- ult: new LuaBuiltinFunction((_sf, m: number, n: number) => {
189
- return untagNumber(m) >>> 0 < untagNumber(n) >>> 0;
190
- }),
191
-
192
- // Keep the cosineSimilarity utility function
193
- cosineSimilarity: new LuaBuiltinFunction(
194
- (sf, vecA: LuaTable | number[], vecB: LuaTable | number[]) => {
335
+ cosh: new LuaBuiltinFunction({
336
+ callback: (_sf, x: number) => Math.cosh(untagNumber(x)),
337
+ description: "Returns the hyperbolic cosine of `x`.",
338
+ parameters: [{ name: "x", type: "number" }],
339
+ returns: [{ type: "number" }],
340
+ deprecated: "Retained for compatibility with older Lua versions.",
341
+ }),
342
+ sinh: new LuaBuiltinFunction({
343
+ callback: (_sf, x: number) => Math.sinh(untagNumber(x)),
344
+ description: "Returns the hyperbolic sine of `x`.",
345
+ parameters: [{ name: "x", type: "number" }],
346
+ returns: [{ type: "number" }],
347
+ deprecated: "Retained for compatibility with older Lua versions.",
348
+ }),
349
+ tanh: new LuaBuiltinFunction({
350
+ callback: (_sf, x: number) => Math.tanh(untagNumber(x)),
351
+ description: "Returns the hyperbolic tangent of `x`.",
352
+ parameters: [{ name: "x", type: "number" }],
353
+ returns: [{ type: "number" }],
354
+ deprecated: "Retained for compatibility with older Lua versions.",
355
+ }),
356
+
357
+ deg: new LuaBuiltinFunction({
358
+ callback: (_sf, x: number) => (untagNumber(x) * 180) / Math.PI,
359
+ description: "Converts an angle from radians to degrees.",
360
+ parameters: [{ name: "x", type: "number" }],
361
+ returns: [{ type: "number" }],
362
+ examples: [{ code: "print(math.deg(math.pi)) -- 180" }],
363
+ }),
364
+ rad: new LuaBuiltinFunction({
365
+ callback: (_sf, x: number) => (untagNumber(x) * Math.PI) / 180,
366
+ description: "Converts an angle from degrees to radians.",
367
+ parameters: [{ name: "x", type: "number" }],
368
+ returns: [{ type: "number" }],
369
+ }),
370
+ ult: new LuaBuiltinFunction({
371
+ callback: (_sf, m: number, n: number) => {
372
+ return untagNumber(m) >>> 0 < untagNumber(n) >>> 0;
373
+ },
374
+ description: "Compares two integers as unsigned 32-bit values.",
375
+ parameters: [
376
+ { name: "m", type: "integer" },
377
+ { name: "n", type: "integer" },
378
+ ],
379
+ returns: [{ type: "boolean" }],
380
+ examples: [{ code: "print(math.ult(2, 3)) -- true" }],
381
+ }),
382
+
383
+ cosineSimilarity: new LuaBuiltinFunction({
384
+ callback: (sf, vecA: LuaTable | number[], vecB: LuaTable | number[]) => {
195
385
  if (vecA instanceof LuaTable) {
196
386
  vecA = vecA.toJSArray();
197
387
  }
@@ -215,5 +405,13 @@ export const mathApi = new LuaTable({
215
405
 
216
406
  return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
217
407
  },
218
- ),
408
+ description:
409
+ "Returns the cosine similarity between two equal-length numeric vectors.",
410
+ parameters: [
411
+ { name: "vecA", type: "table" },
412
+ { name: "vecB", type: "table" },
413
+ ],
414
+ returns: [{ type: "number", description: "Cosine similarity." }],
415
+ examples: [{ code: "print(math.cosineSimilarity({1, 2, 3}, {4, 5, 6}))" }],
416
+ }),
219
417
  });
@@ -7,12 +7,11 @@ import { fsEndpoint } from "../../spaces/constants.ts";
7
7
  import { LuaNativeJSFunction, LuaTable } from "../runtime.ts";
8
8
 
9
9
  export const netApi = new LuaTable({
10
- proxyFetch: new LuaNativeJSFunction(
11
- async (
10
+ proxyFetch: new LuaNativeJSFunction({
11
+ callback: async (
12
12
  url: string,
13
13
  options: ProxyFetchRequest = {},
14
14
  ): Promise<ProxyFetchResponse> => {
15
- // JSONify any non-serializable body
16
15
  if (
17
16
  options?.body &&
18
17
  typeof options.body !== "string" &&
@@ -40,7 +39,6 @@ export const netApi = new LuaTable({
40
39
  body: await resp.text(),
41
40
  };
42
41
  }
43
- // Do sensible things with the body based on the content type
44
42
  // Read as ArrayBuffer first to safely handle empty responses (e.g.
45
43
  // PUT/DELETE returning 204 with Content-Type: application/json).
46
44
  // resp.arrayBuffer() never throws on an empty body, whereas
@@ -70,30 +68,76 @@ export const netApi = new LuaTable({
70
68
  body: body,
71
69
  };
72
70
  },
73
- ),
74
- readURI: new LuaNativeJSFunction(
75
- (uri: string, options: { uri?: string; encoding?: string } = {}) => {
71
+ description:
72
+ "Performs an HTTP request through the SilverBullet server to avoid browser CORS restrictions.",
73
+ signatures: ["net.proxyFetch(url, options?)"],
74
+ parameters: [
75
+ { name: "url", type: "string", description: "URL to request." },
76
+ {
77
+ name: "options",
78
+ type: "table",
79
+ description:
80
+ "Optional method, headers, body, and responseEncoding values.",
81
+ optional: true,
82
+ },
83
+ ],
84
+ returns: [
85
+ {
86
+ type: "table",
87
+ description: "Response status, headers, decoded body, and ok flag.",
88
+ },
89
+ ],
90
+ see: "API/net",
91
+ }),
92
+ readURI: new LuaNativeJSFunction({
93
+ callback: (
94
+ uri: string,
95
+ options: { uri?: string; encoding?: string } = {},
96
+ ) => {
76
97
  options.uri = uri;
77
98
  return client.clientSystem.serviceRegistry.invokeBestMatch(
78
99
  `net.readURI:${uri}`,
79
100
  options,
80
101
  );
81
102
  },
82
- ),
83
- writeURI: new LuaNativeJSFunction(
84
- (uri: string, content: string | Uint8Array) => {
103
+ description: "Reads content from a URI using the best matching service.",
104
+ signatures: ["net.readURI(uri, options?)"],
105
+ parameters: [
106
+ { name: "uri", type: "string", description: "URI to read." },
107
+ {
108
+ name: "options",
109
+ type: "table",
110
+ description: "Optional service-specific values such as encoding.",
111
+ optional: true,
112
+ },
113
+ ],
114
+ returns: [{ description: "Content returned by the matching service." }],
115
+ see: "API/net",
116
+ }),
117
+ writeURI: new LuaNativeJSFunction({
118
+ callback: (uri: string, content: string | Uint8Array) => {
85
119
  return client.clientSystem.serviceRegistry.invokeBestMatch(
86
120
  `net.writeURI:${uri}`,
87
121
  { uri, content },
88
122
  );
89
123
  },
90
- ),
124
+ description: "Writes content to a URI using the best matching service.",
125
+ signatures: ["net.writeURI(uri, content)"],
126
+ parameters: [
127
+ { name: "uri", type: "string", description: "URI to write." },
128
+ {
129
+ name: "content",
130
+ type: "string|userdata",
131
+ description: "Text or binary content to write.",
132
+ },
133
+ ],
134
+ returns: [{ description: "Result returned by the matching service." }],
135
+ see: "API/net",
136
+ }),
91
137
  });
92
138
 
93
- // Utility functions
94
139
  function buildProxyUrl(client: Client, url: string) {
95
140
  url = url.replace(/^https?:\/\//, "");
96
- // Strip off the /.fs and replace with /.proxy
97
141
  return (
98
142
  client.httpSpacePrimitives.url.slice(0, -fsEndpoint.length) +
99
143
  "/.proxy/" +