@rezless/vm 0.1.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.
- package/LICENSE +202 -0
- package/NOTICE +32 -0
- package/dist/builtins/base64.d.ts +25 -0
- package/dist/builtins/base64.d.ts.map +1 -0
- package/dist/builtins/base64.js +43 -0
- package/dist/builtins/base64.js.map +1 -0
- package/dist/builtins/chat.d.ts +10 -0
- package/dist/builtins/chat.d.ts.map +1 -0
- package/dist/builtins/chat.js +36 -0
- package/dist/builtins/chat.js.map +1 -0
- package/dist/builtins/dataserver.d.ts +26 -0
- package/dist/builtins/dataserver.d.ts.map +1 -0
- package/dist/builtins/dataserver.js +20 -0
- package/dist/builtins/dataserver.js.map +1 -0
- package/dist/builtins/detected.d.ts +40 -0
- package/dist/builtins/detected.d.ts.map +1 -0
- package/dist/builtins/detected.js +23 -0
- package/dist/builtins/detected.js.map +1 -0
- package/dist/builtins/hash.d.ts +6 -0
- package/dist/builtins/hash.d.ts.map +1 -0
- package/dist/builtins/hash.js +34 -0
- package/dist/builtins/hash.js.map +1 -0
- package/dist/builtins/http.d.ts +40 -0
- package/dist/builtins/http.d.ts.map +1 -0
- package/dist/builtins/http.js +87 -0
- package/dist/builtins/http.js.map +1 -0
- package/dist/builtins/identity.d.ts +14 -0
- package/dist/builtins/identity.d.ts.map +1 -0
- package/dist/builtins/identity.js +17 -0
- package/dist/builtins/identity.js.map +1 -0
- package/dist/builtins/index.d.ts +8 -0
- package/dist/builtins/index.d.ts.map +1 -0
- package/dist/builtins/index.js +232 -0
- package/dist/builtins/index.js.map +1 -0
- package/dist/builtins/inventory.d.ts +33 -0
- package/dist/builtins/inventory.d.ts.map +1 -0
- package/dist/builtins/inventory.js +134 -0
- package/dist/builtins/inventory.js.map +1 -0
- package/dist/builtins/json.d.ts +7 -0
- package/dist/builtins/json.d.ts.map +1 -0
- package/dist/builtins/json.js +690 -0
- package/dist/builtins/json.js.map +1 -0
- package/dist/builtins/link-info.d.ts +10 -0
- package/dist/builtins/link-info.d.ts.map +1 -0
- package/dist/builtins/link-info.js +26 -0
- package/dist/builtins/link-info.js.map +1 -0
- package/dist/builtins/linked.d.ts +23 -0
- package/dist/builtins/linked.d.ts.map +1 -0
- package/dist/builtins/linked.js +20 -0
- package/dist/builtins/linked.js.map +1 -0
- package/dist/builtins/linksetdata.d.ts +20 -0
- package/dist/builtins/linksetdata.d.ts.map +1 -0
- package/dist/builtins/linksetdata.js +196 -0
- package/dist/builtins/linksetdata.js.map +1 -0
- package/dist/builtins/listen.d.ts +33 -0
- package/dist/builtins/listen.d.ts.map +1 -0
- package/dist/builtins/listen.js +45 -0
- package/dist/builtins/listen.js.map +1 -0
- package/dist/builtins/lists.d.ts +37 -0
- package/dist/builtins/lists.d.ts.map +1 -0
- package/dist/builtins/lists.js +275 -0
- package/dist/builtins/lists.js.map +1 -0
- package/dist/builtins/math.d.ts +32 -0
- package/dist/builtins/math.d.ts.map +1 -0
- package/dist/builtins/math.js +104 -0
- package/dist/builtins/math.js.map +1 -0
- package/dist/builtins/object.d.ts +29 -0
- package/dist/builtins/object.d.ts.map +1 -0
- package/dist/builtins/object.js +50 -0
- package/dist/builtins/object.js.map +1 -0
- package/dist/builtins/prim-accessors.d.ts +56 -0
- package/dist/builtins/prim-accessors.d.ts.map +1 -0
- package/dist/builtins/prim-accessors.js +353 -0
- package/dist/builtins/prim-accessors.js.map +1 -0
- package/dist/builtins/prim-params.d.ts +12 -0
- package/dist/builtins/prim-params.d.ts.map +1 -0
- package/dist/builtins/prim-params.js +124 -0
- package/dist/builtins/prim-params.js.map +1 -0
- package/dist/builtins/script-control.d.ts +13 -0
- package/dist/builtins/script-control.d.ts.map +1 -0
- package/dist/builtins/script-control.js +41 -0
- package/dist/builtins/script-control.js.map +1 -0
- package/dist/builtins/strings.d.ts +23 -0
- package/dist/builtins/strings.d.ts.map +1 -0
- package/dist/builtins/strings.js +130 -0
- package/dist/builtins/strings.js.map +1 -0
- package/dist/builtins/time.d.ts +28 -0
- package/dist/builtins/time.d.ts.map +1 -0
- package/dist/builtins/time.js +54 -0
- package/dist/builtins/time.js.map +1 -0
- package/dist/clock.d.ts +75 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +125 -0
- package/dist/clock.js.map +1 -0
- package/dist/coverage.d.ts +110 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +221 -0
- package/dist/coverage.js.map +1 -0
- package/dist/dispatch.d.ts +19 -0
- package/dist/dispatch.d.ts.map +1 -0
- package/dist/dispatch.js +42 -0
- package/dist/dispatch.js.map +1 -0
- package/dist/env.d.ts +33 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +76 -0
- package/dist/env.js.map +1 -0
- package/dist/generated/constants.d.ts +967 -0
- package/dist/generated/constants.d.ts.map +1 -0
- package/dist/generated/constants.js +969 -0
- package/dist/generated/constants.js.map +1 -0
- package/dist/generated/constants_table.d.ts +11 -0
- package/dist/generated/constants_table.d.ts.map +1 -0
- package/dist/generated/constants_table.js +978 -0
- package/dist/generated/constants_table.js.map +1 -0
- package/dist/generated/events.d.ts +545 -0
- package/dist/generated/events.d.ts.map +1 -0
- package/dist/generated/events.js +49 -0
- package/dist/generated/events.js.map +1 -0
- package/dist/generated/functions.d.ts +6051 -0
- package/dist/generated/functions.d.ts.map +1 -0
- package/dist/generated/functions.js +526 -0
- package/dist/generated/functions.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/interpreter.d.ts +39 -0
- package/dist/interpreter.d.ts.map +1 -0
- package/dist/interpreter.js +381 -0
- package/dist/interpreter.js.map +1 -0
- package/dist/inventory.d.ts +52 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +45 -0
- package/dist/inventory.js.map +1 -0
- package/dist/linkset.d.ts +89 -0
- package/dist/linkset.d.ts.map +1 -0
- package/dist/linkset.js +179 -0
- package/dist/linkset.js.map +1 -0
- package/dist/prim-params.d.ts +221 -0
- package/dist/prim-params.d.ts.map +1 -0
- package/dist/prim-params.js +852 -0
- package/dist/prim-params.js.map +1 -0
- package/dist/prim.d.ts +79 -0
- package/dist/prim.d.ts.map +1 -0
- package/dist/prim.js +96 -0
- package/dist/prim.js.map +1 -0
- package/dist/random.d.ts +16 -0
- package/dist/random.d.ts.map +1 -0
- package/dist/random.js +29 -0
- package/dist/random.js.map +1 -0
- package/dist/runtime.d.ts +108 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +2 -0
- package/dist/runtime.js.map +1 -0
- package/dist/script.d.ts +248 -0
- package/dist/script.d.ts.map +1 -0
- package/dist/script.js +667 -0
- package/dist/script.js.map +1 -0
- package/dist/values/coerce.d.ts +22 -0
- package/dist/values/coerce.d.ts.map +1 -0
- package/dist/values/coerce.js +184 -0
- package/dist/values/coerce.js.map +1 -0
- package/dist/values/format.d.ts +20 -0
- package/dist/values/format.d.ts.map +1 -0
- package/dist/values/format.js +47 -0
- package/dist/values/format.js.map +1 -0
- package/dist/values/ops.d.ts +19 -0
- package/dist/values/ops.d.ts.map +1 -0
- package/dist/values/ops.js +345 -0
- package/dist/values/ops.js.map +1 -0
- package/dist/values/types.d.ts +39 -0
- package/dist/values/types.d.ts.map +1 -0
- package/dist/values/types.js +68 -0
- package/dist/values/types.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { STRING_TRIM_HEAD, STRING_TRIM_TAIL } from '../generated/constants.js';
|
|
2
|
+
/** llStringLength(string s) — Unicode code-point count, not byte count. */
|
|
3
|
+
export const llStringLength = (_ctx, args) => {
|
|
4
|
+
const s = args[0] ?? '';
|
|
5
|
+
return [...s].length;
|
|
6
|
+
};
|
|
7
|
+
/** llSubStringIndex(string source, string pattern) — first index, or -1. */
|
|
8
|
+
export const llSubStringIndex = (_ctx, args) => {
|
|
9
|
+
const src = args[0] ?? '';
|
|
10
|
+
const pat = args[1] ?? '';
|
|
11
|
+
return src.indexOf(pat);
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* llGetSubString(string src, integer start, integer end)
|
|
15
|
+
*
|
|
16
|
+
* Inclusive bounds. Negative indices count back from the end (so -1 is the
|
|
17
|
+
* last character). If start > end, LSL wraps: returns chars [0..end] +
|
|
18
|
+
* [start..length-1] concatenated.
|
|
19
|
+
*/
|
|
20
|
+
export const llGetSubString = (_ctx, args) => {
|
|
21
|
+
const src = args[0] ?? '';
|
|
22
|
+
const start = args[1] ?? 0;
|
|
23
|
+
const end = args[2] ?? 0;
|
|
24
|
+
return sliceLslString(src, start, end);
|
|
25
|
+
};
|
|
26
|
+
/** llDeleteSubString — same wrap rules as llGetSubString but in reverse. */
|
|
27
|
+
export const llDeleteSubString = (_ctx, args) => {
|
|
28
|
+
const src = args[0] ?? '';
|
|
29
|
+
const start = args[1] ?? 0;
|
|
30
|
+
const end = args[2] ?? 0;
|
|
31
|
+
return deleteLslSubString(src, start, end);
|
|
32
|
+
};
|
|
33
|
+
export const llInsertString = (_ctx, args) => {
|
|
34
|
+
const src = args[0] ?? '';
|
|
35
|
+
const pos = args[1] ?? 0;
|
|
36
|
+
const text = args[2] ?? '';
|
|
37
|
+
const safe = clampInsertPos(src, pos);
|
|
38
|
+
return src.slice(0, safe) + text + src.slice(safe);
|
|
39
|
+
};
|
|
40
|
+
export const llStringTrim = (_ctx, args) => {
|
|
41
|
+
const src = args[0] ?? '';
|
|
42
|
+
const flags = args[1] ?? 0;
|
|
43
|
+
let s = src;
|
|
44
|
+
if (flags & STRING_TRIM_HEAD)
|
|
45
|
+
s = s.replace(/^\s+/, '');
|
|
46
|
+
if (flags & STRING_TRIM_TAIL)
|
|
47
|
+
s = s.replace(/\s+$/, '');
|
|
48
|
+
return s;
|
|
49
|
+
};
|
|
50
|
+
export const llToLower = (_ctx, args) => (args[0] ?? '').toLowerCase();
|
|
51
|
+
export const llToUpper = (_ctx, args) => (args[0] ?? '').toUpperCase();
|
|
52
|
+
export const llReplaceSubString = (_ctx, args) => {
|
|
53
|
+
const src = args[0] ?? '';
|
|
54
|
+
const pattern = args[1] ?? '';
|
|
55
|
+
const replacement = args[2] ?? '';
|
|
56
|
+
const count = args[3] ?? 0;
|
|
57
|
+
if (!pattern)
|
|
58
|
+
return src;
|
|
59
|
+
if (count === 0)
|
|
60
|
+
return src.split(pattern).join(replacement);
|
|
61
|
+
let out = src;
|
|
62
|
+
if (count > 0) {
|
|
63
|
+
let remaining = count;
|
|
64
|
+
let result = '';
|
|
65
|
+
let rest = out;
|
|
66
|
+
while (remaining > 0) {
|
|
67
|
+
const idx = rest.indexOf(pattern);
|
|
68
|
+
if (idx < 0)
|
|
69
|
+
break;
|
|
70
|
+
result += rest.slice(0, idx) + replacement;
|
|
71
|
+
rest = rest.slice(idx + pattern.length);
|
|
72
|
+
remaining--;
|
|
73
|
+
}
|
|
74
|
+
return result + rest;
|
|
75
|
+
}
|
|
76
|
+
// count < 0: replace from end, |count| times.
|
|
77
|
+
let n = -count;
|
|
78
|
+
let result = out;
|
|
79
|
+
while (n > 0) {
|
|
80
|
+
const idx = result.lastIndexOf(pattern);
|
|
81
|
+
if (idx < 0)
|
|
82
|
+
break;
|
|
83
|
+
result = result.slice(0, idx) + replacement + result.slice(idx + pattern.length);
|
|
84
|
+
n--;
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
};
|
|
88
|
+
export const llEscapeURL = (_ctx, args) => encodeURIComponent(args[0] ?? '');
|
|
89
|
+
export const llUnescapeURL = (_ctx, args) => {
|
|
90
|
+
try {
|
|
91
|
+
return decodeURIComponent(args[0] ?? '');
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return '';
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
// ---- Helpers ----
|
|
98
|
+
function normalizeIndex(i, length) {
|
|
99
|
+
return i < 0 ? Math.max(0, length + i) : Math.min(length - 1, i);
|
|
100
|
+
}
|
|
101
|
+
function sliceLslString(src, start, end) {
|
|
102
|
+
const len = src.length;
|
|
103
|
+
if (len === 0)
|
|
104
|
+
return '';
|
|
105
|
+
const a = normalizeIndex(start, len);
|
|
106
|
+
const b = normalizeIndex(end, len);
|
|
107
|
+
if (a <= b)
|
|
108
|
+
return src.slice(a, b + 1);
|
|
109
|
+
// LSL "exclusive" slice: returns [0..b] + [a..end]
|
|
110
|
+
return src.slice(0, b + 1) + src.slice(a);
|
|
111
|
+
}
|
|
112
|
+
function deleteLslSubString(src, start, end) {
|
|
113
|
+
const len = src.length;
|
|
114
|
+
if (len === 0)
|
|
115
|
+
return src;
|
|
116
|
+
const a = normalizeIndex(start, len);
|
|
117
|
+
const b = normalizeIndex(end, len);
|
|
118
|
+
if (a <= b)
|
|
119
|
+
return src.slice(0, a) + src.slice(b + 1);
|
|
120
|
+
// Wrapped: keep just the slice between b and a (exclusive).
|
|
121
|
+
return src.slice(b + 1, a);
|
|
122
|
+
}
|
|
123
|
+
function clampInsertPos(src, pos) {
|
|
124
|
+
if (pos < 0)
|
|
125
|
+
return 0;
|
|
126
|
+
if (pos > src.length)
|
|
127
|
+
return src.length;
|
|
128
|
+
return pos;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=strings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.js","sourceRoot":"","sources":["../../src/builtins/strings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BuiltinImpl } from '../runtime.js';
|
|
2
|
+
/**
|
|
3
|
+
* Time and timer built-ins. All operate on the virtual clock; no real
|
|
4
|
+
* wall-clock time is read.
|
|
5
|
+
*/
|
|
6
|
+
/** llSetTimerEvent(float sec) — `sec <= 0` cancels; otherwise (re)arms. */
|
|
7
|
+
export declare const llSetTimerEvent: BuiltinImpl;
|
|
8
|
+
/**
|
|
9
|
+
* llSleep(float sec) — synchronously advances the virtual clock.
|
|
10
|
+
*
|
|
11
|
+
* Per LSL:
|
|
12
|
+
* - `sec <= 0` is a no-op; the script does not sleep at all.
|
|
13
|
+
* - For positive `sec`, the wait is at least one server frame (~22.22 ms
|
|
14
|
+
* at 45 Hz), so e.g. `llSleep(0.001)` actually waits ~22 ms.
|
|
15
|
+
*
|
|
16
|
+
* Events that arrive while the script is sleeping queue up but don't fire
|
|
17
|
+
* on the calling script until the current handler returns. We model that
|
|
18
|
+
* by advancing the linkset clock; the queue drain happens at the handler
|
|
19
|
+
* boundary (inside Script.runHandler).
|
|
20
|
+
*/
|
|
21
|
+
export declare const llSleep: BuiltinImpl;
|
|
22
|
+
/** llGetTime() — seconds since script start (or last llResetTime). */
|
|
23
|
+
export declare const llGetTime: BuiltinImpl;
|
|
24
|
+
/** llGetAndResetTime() — returns elapsed and resets in one atomic step. */
|
|
25
|
+
export declare const llGetAndResetTime: BuiltinImpl;
|
|
26
|
+
/** llResetTime() — snapshot now as the new reference for llGetTime. */
|
|
27
|
+
export declare const llResetTime: BuiltinImpl;
|
|
28
|
+
//# sourceMappingURL=time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/builtins/time.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD;;;GAGG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,eAAe,EAAE,WAI7B,CAAA;AAUD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,EAAE,WAMrB,CAAA;AAED,sEAAsE;AACtE,eAAO,MAAM,SAAS,EAAE,WAEvB,CAAA;AAED,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,EAAE,WAI/B,CAAA;AAED,uEAAuE;AACvE,eAAO,MAAM,WAAW,EAAE,WAGzB,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time and timer built-ins. All operate on the virtual clock; no real
|
|
3
|
+
* wall-clock time is read.
|
|
4
|
+
*/
|
|
5
|
+
/** llSetTimerEvent(float sec) — `sec <= 0` cancels; otherwise (re)arms. */
|
|
6
|
+
export const llSetTimerEvent = (ctx, args) => {
|
|
7
|
+
const seconds = args[0] ?? 0;
|
|
8
|
+
ctx.state.clock.setTimer(seconds * 1000);
|
|
9
|
+
return undefined;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Minimum llSleep advance for positive durations: one server frame at the
|
|
13
|
+
* LSL-canonical 45 Hz tick (~22.222 ms). `llSleep(0)` and negative values
|
|
14
|
+
* are no-ops per the LSL wiki — they are early-returned before this floor
|
|
15
|
+
* is applied.
|
|
16
|
+
*/
|
|
17
|
+
const FRAME_MS = 1000 / 45;
|
|
18
|
+
/**
|
|
19
|
+
* llSleep(float sec) — synchronously advances the virtual clock.
|
|
20
|
+
*
|
|
21
|
+
* Per LSL:
|
|
22
|
+
* - `sec <= 0` is a no-op; the script does not sleep at all.
|
|
23
|
+
* - For positive `sec`, the wait is at least one server frame (~22.22 ms
|
|
24
|
+
* at 45 Hz), so e.g. `llSleep(0.001)` actually waits ~22 ms.
|
|
25
|
+
*
|
|
26
|
+
* Events that arrive while the script is sleeping queue up but don't fire
|
|
27
|
+
* on the calling script until the current handler returns. We model that
|
|
28
|
+
* by advancing the linkset clock; the queue drain happens at the handler
|
|
29
|
+
* boundary (inside Script.runHandler).
|
|
30
|
+
*/
|
|
31
|
+
export const llSleep = (ctx, args) => {
|
|
32
|
+
const seconds = args[0] ?? 0;
|
|
33
|
+
if (seconds <= 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
const ms = Math.max(FRAME_MS, seconds * 1000);
|
|
36
|
+
ctx.state.clock.advance(ms);
|
|
37
|
+
return undefined;
|
|
38
|
+
};
|
|
39
|
+
/** llGetTime() — seconds since script start (or last llResetTime). */
|
|
40
|
+
export const llGetTime = (ctx) => {
|
|
41
|
+
return ctx.state.clock.elapsedSeconds();
|
|
42
|
+
};
|
|
43
|
+
/** llGetAndResetTime() — returns elapsed and resets in one atomic step. */
|
|
44
|
+
export const llGetAndResetTime = (ctx) => {
|
|
45
|
+
const elapsed = ctx.state.clock.elapsedSeconds();
|
|
46
|
+
ctx.state.clock.resetReference();
|
|
47
|
+
return elapsed;
|
|
48
|
+
};
|
|
49
|
+
/** llResetTime() — snapshot now as the new reference for llGetTime. */
|
|
50
|
+
export const llResetTime = (ctx) => {
|
|
51
|
+
ctx.state.clock.resetReference();
|
|
52
|
+
return undefined;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/builtins/time.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,eAAe,GAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IACxD,MAAM,OAAO,GAAI,IAAI,CAAC,CAAC,CAAwB,IAAI,CAAC,CAAA;IACpD,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IACxC,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAA;AAE1B;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,OAAO,GAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IAChD,MAAM,OAAO,GAAI,IAAI,CAAC,CAAC,CAAwB,IAAI,CAAC,CAAA;IACpD,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,SAAS,CAAA;IAClC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,CAAA;IAC7C,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC3B,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED,sEAAsE;AACtE,MAAM,CAAC,MAAM,SAAS,GAAgB,CAAC,GAAG,EAAE,EAAE;IAC5C,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;AACzC,CAAC,CAAA;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAgB,CAAC,GAAG,EAAE,EAAE;IACpD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;IAChD,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;IAChC,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,uEAAuE;AACvE,MAAM,CAAC,MAAM,WAAW,GAAgB,CAAC,GAAG,EAAE,EAAE;IAC9C,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;IAChC,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA"}
|
package/dist/clock.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Virtual clock + event queue.
|
|
3
|
+
*
|
|
4
|
+
* The clock is the only source of "time" in the VM. Tests advance it
|
|
5
|
+
* explicitly (`vm.advanceTime` / `linkset.advanceTime`); LSL scripts advance
|
|
6
|
+
* it by calling `llSleep` or `llSetTimerEvent`. Real wall-clock time is
|
|
7
|
+
* never read.
|
|
8
|
+
*
|
|
9
|
+
* The queue is **linkset-wide**: every script in the linkset shares one
|
|
10
|
+
* `now` and one event queue. Each queued event carries a `target: Script`
|
|
11
|
+
* — the script whose handler will run when the event fires. Per-script
|
|
12
|
+
* state (timer interval, llGetTime reference) lives on `ScriptClockView`,
|
|
13
|
+
* a thin facade exposed to builtins as `ctx.state.clock`.
|
|
14
|
+
*/
|
|
15
|
+
import type { Script } from './script.js';
|
|
16
|
+
export interface QueuedEvent {
|
|
17
|
+
/** Virtual ms timestamp at which this event becomes ready to fire. */
|
|
18
|
+
readonly at: number;
|
|
19
|
+
/** Script whose handler is invoked when the event fires. */
|
|
20
|
+
readonly target: Script;
|
|
21
|
+
readonly event: string;
|
|
22
|
+
readonly payload: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
/** Linkset-wide clock. One instance per Linkset. */
|
|
25
|
+
export declare class LinksetClock {
|
|
26
|
+
/** Virtual milliseconds since linkset construction. Strictly monotonic. */
|
|
27
|
+
now: number;
|
|
28
|
+
private readonly queue;
|
|
29
|
+
/** Schedule a one-shot event on `target`'s handler at virtual time `at`. */
|
|
30
|
+
schedule(target: Script, at: number, event: string, payload?: Record<string, unknown>): void;
|
|
31
|
+
/** Move the clock forward unconditionally; does not drain queues. */
|
|
32
|
+
advance(ms: number): void;
|
|
33
|
+
/**
|
|
34
|
+
* Pop and return the next due event (`at <= now`) considering all queued
|
|
35
|
+
* one-shots and every script's recurring timer. Returns `null` when no
|
|
36
|
+
* event is ready.
|
|
37
|
+
*
|
|
38
|
+
* Recurring timers fire once per script per interval; their next fire
|
|
39
|
+
* timestamp is advanced by `at + interval` (not `now + interval`) so that
|
|
40
|
+
* long advances catch up on every missed fire.
|
|
41
|
+
*/
|
|
42
|
+
takeNextDue(scripts: ReadonlyArray<Script>): QueuedEvent | null;
|
|
43
|
+
/** Snapshot of the pending one-shot queue. Read-only; for inspection/tests. */
|
|
44
|
+
pendingEvents(): readonly QueuedEvent[];
|
|
45
|
+
/** Remove every queued event whose target is `script`. Used on reset. */
|
|
46
|
+
purgeTarget(script: Script): void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Per-script clock facade. Builtins read `ctx.state.clock` and call
|
|
50
|
+
* `.schedule()` / `.setTimer()` / `.elapsedSeconds()` against this view; it
|
|
51
|
+
* forwards shared state to the linkset and keeps per-script state local.
|
|
52
|
+
*/
|
|
53
|
+
export declare class ScriptClockView {
|
|
54
|
+
private readonly linksetClock;
|
|
55
|
+
private readonly self;
|
|
56
|
+
/** Reference time for `llGetTime`/`llResetTime` (virtual ms). */
|
|
57
|
+
timeReferenceMs: number;
|
|
58
|
+
/** Recurring timer interval in ms; 0 = no timer. */
|
|
59
|
+
timerIntervalMs: number;
|
|
60
|
+
/** Virtual time at which the next timer event fires. */
|
|
61
|
+
timerNextFireMs: number;
|
|
62
|
+
constructor(linksetClock: LinksetClock, self: () => Script);
|
|
63
|
+
get now(): number;
|
|
64
|
+
/** Schedule a one-shot event on this script. */
|
|
65
|
+
schedule(at: number, event: string, payload?: Record<string, unknown>): void;
|
|
66
|
+
/** Schedule a one-shot event on a specific script. */
|
|
67
|
+
scheduleOn(target: Script, at: number, event: string, payload?: Record<string, unknown>): void;
|
|
68
|
+
cancelTimer(): void;
|
|
69
|
+
setTimer(intervalMs: number): void;
|
|
70
|
+
/** Advances the linkset clock — used by `llSleep`. */
|
|
71
|
+
advance(ms: number): void;
|
|
72
|
+
elapsedSeconds(): number;
|
|
73
|
+
resetReference(): void;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=clock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC1C;AAED,oDAAoD;AACpD,qBAAa,YAAY;IACvB,2EAA2E;IAC3E,GAAG,SAAI;IAEP,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAE1C,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAIhG,qEAAqE;IACrE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKzB;;;;;;;;OAQG;IACH,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,WAAW,GAAG,IAAI;IAqC/D,+EAA+E;IAC/E,aAAa,IAAI,SAAS,WAAW,EAAE;IAIvC,yEAAyE;IACzE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAKlC;AAED;;;;GAIG;AACH,qBAAa,eAAe;IASxB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IATvB,iEAAiE;IACjE,eAAe,SAAI;IACnB,oDAAoD;IACpD,eAAe,SAAI;IACnB,wDAAwD;IACxD,eAAe,SAAI;gBAGA,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,MAAM,MAAM;IAGrC,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAIhF,sDAAsD;IACtD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAIlG,WAAW,IAAI,IAAI;IAKnB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IASlC,sDAAsD;IACtD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIzB,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,IAAI;CAGvB"}
|
package/dist/clock.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/** Linkset-wide clock. One instance per Linkset. */
|
|
2
|
+
export class LinksetClock {
|
|
3
|
+
/** Virtual milliseconds since linkset construction. Strictly monotonic. */
|
|
4
|
+
now = 0;
|
|
5
|
+
queue = [];
|
|
6
|
+
/** Schedule a one-shot event on `target`'s handler at virtual time `at`. */
|
|
7
|
+
schedule(target, at, event, payload = {}) {
|
|
8
|
+
this.queue.push({ at, target, event, payload });
|
|
9
|
+
}
|
|
10
|
+
/** Move the clock forward unconditionally; does not drain queues. */
|
|
11
|
+
advance(ms) {
|
|
12
|
+
if (ms < 0)
|
|
13
|
+
throw new Error('cannot advance time backwards');
|
|
14
|
+
this.now += ms;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Pop and return the next due event (`at <= now`) considering all queued
|
|
18
|
+
* one-shots and every script's recurring timer. Returns `null` when no
|
|
19
|
+
* event is ready.
|
|
20
|
+
*
|
|
21
|
+
* Recurring timers fire once per script per interval; their next fire
|
|
22
|
+
* timestamp is advanced by `at + interval` (not `now + interval`) so that
|
|
23
|
+
* long advances catch up on every missed fire.
|
|
24
|
+
*/
|
|
25
|
+
takeNextDue(scripts) {
|
|
26
|
+
let bestIdx = -1;
|
|
27
|
+
let bestAt = Infinity;
|
|
28
|
+
for (let i = 0; i < this.queue.length; i++) {
|
|
29
|
+
const e = this.queue[i];
|
|
30
|
+
if (e.at <= this.now && e.at < bestAt) {
|
|
31
|
+
bestAt = e.at;
|
|
32
|
+
bestIdx = i;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
let bestTimerScript = null;
|
|
36
|
+
let bestTimerAt = Infinity;
|
|
37
|
+
for (const s of scripts) {
|
|
38
|
+
// Per LSL: dead and stopped scripts don't generate timer events. Skip
|
|
39
|
+
// their timer state so we don't waste catch-up iterations or accumulate
|
|
40
|
+
// back-logged events that flood the script on resume.
|
|
41
|
+
if (s.dead || !s.running)
|
|
42
|
+
continue;
|
|
43
|
+
const v = s.clockView;
|
|
44
|
+
if (v.timerIntervalMs > 0 && v.timerNextFireMs <= this.now && v.timerNextFireMs < bestTimerAt) {
|
|
45
|
+
bestTimerAt = v.timerNextFireMs;
|
|
46
|
+
bestTimerScript = s;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (bestIdx === -1 && bestTimerScript === null)
|
|
50
|
+
return null;
|
|
51
|
+
if (bestTimerScript && bestTimerAt <= bestAt) {
|
|
52
|
+
const at = bestTimerAt;
|
|
53
|
+
const v = bestTimerScript.clockView;
|
|
54
|
+
v.timerNextFireMs = at + v.timerIntervalMs;
|
|
55
|
+
return { at, target: bestTimerScript, event: 'timer', payload: {} };
|
|
56
|
+
}
|
|
57
|
+
const ev = this.queue[bestIdx];
|
|
58
|
+
this.queue.splice(bestIdx, 1);
|
|
59
|
+
return ev;
|
|
60
|
+
}
|
|
61
|
+
/** Snapshot of the pending one-shot queue. Read-only; for inspection/tests. */
|
|
62
|
+
pendingEvents() {
|
|
63
|
+
return this.queue.slice();
|
|
64
|
+
}
|
|
65
|
+
/** Remove every queued event whose target is `script`. Used on reset. */
|
|
66
|
+
purgeTarget(script) {
|
|
67
|
+
for (let i = this.queue.length - 1; i >= 0; i--) {
|
|
68
|
+
if (this.queue[i].target === script)
|
|
69
|
+
this.queue.splice(i, 1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Per-script clock facade. Builtins read `ctx.state.clock` and call
|
|
75
|
+
* `.schedule()` / `.setTimer()` / `.elapsedSeconds()` against this view; it
|
|
76
|
+
* forwards shared state to the linkset and keeps per-script state local.
|
|
77
|
+
*/
|
|
78
|
+
export class ScriptClockView {
|
|
79
|
+
linksetClock;
|
|
80
|
+
self;
|
|
81
|
+
/** Reference time for `llGetTime`/`llResetTime` (virtual ms). */
|
|
82
|
+
timeReferenceMs = 0;
|
|
83
|
+
/** Recurring timer interval in ms; 0 = no timer. */
|
|
84
|
+
timerIntervalMs = 0;
|
|
85
|
+
/** Virtual time at which the next timer event fires. */
|
|
86
|
+
timerNextFireMs = 0;
|
|
87
|
+
constructor(linksetClock, self) {
|
|
88
|
+
this.linksetClock = linksetClock;
|
|
89
|
+
this.self = self;
|
|
90
|
+
}
|
|
91
|
+
get now() {
|
|
92
|
+
return this.linksetClock.now;
|
|
93
|
+
}
|
|
94
|
+
/** Schedule a one-shot event on this script. */
|
|
95
|
+
schedule(at, event, payload = {}) {
|
|
96
|
+
this.linksetClock.schedule(this.self(), at, event, payload);
|
|
97
|
+
}
|
|
98
|
+
/** Schedule a one-shot event on a specific script. */
|
|
99
|
+
scheduleOn(target, at, event, payload = {}) {
|
|
100
|
+
this.linksetClock.schedule(target, at, event, payload);
|
|
101
|
+
}
|
|
102
|
+
cancelTimer() {
|
|
103
|
+
this.timerIntervalMs = 0;
|
|
104
|
+
this.timerNextFireMs = 0;
|
|
105
|
+
}
|
|
106
|
+
setTimer(intervalMs) {
|
|
107
|
+
if (intervalMs <= 0) {
|
|
108
|
+
this.cancelTimer();
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
this.timerIntervalMs = intervalMs;
|
|
112
|
+
this.timerNextFireMs = this.now + intervalMs;
|
|
113
|
+
}
|
|
114
|
+
/** Advances the linkset clock — used by `llSleep`. */
|
|
115
|
+
advance(ms) {
|
|
116
|
+
this.linksetClock.advance(ms);
|
|
117
|
+
}
|
|
118
|
+
elapsedSeconds() {
|
|
119
|
+
return (this.now - this.timeReferenceMs) / 1000;
|
|
120
|
+
}
|
|
121
|
+
resetReference() {
|
|
122
|
+
this.timeReferenceMs = this.now;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=clock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.js","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Script as Ast, Statement, SourceLocation } from '@rezless/parser';
|
|
2
|
+
export type StatementKind = Statement['kind'];
|
|
3
|
+
export interface StatementInfo {
|
|
4
|
+
readonly id: number;
|
|
5
|
+
readonly line: number;
|
|
6
|
+
readonly col: number;
|
|
7
|
+
readonly kind: StatementKind;
|
|
8
|
+
}
|
|
9
|
+
export type BranchKind = 'if' | 'while' | 'do-while' | 'for';
|
|
10
|
+
export interface BranchInfo {
|
|
11
|
+
readonly id: number;
|
|
12
|
+
readonly line: number;
|
|
13
|
+
readonly col: number;
|
|
14
|
+
readonly kind: BranchKind;
|
|
15
|
+
/** False when the AST has no `else` arm — the implicit-else outcome still
|
|
16
|
+
* counts toward branch coverage when the test ever evaluates false. */
|
|
17
|
+
readonly hasElse: boolean;
|
|
18
|
+
}
|
|
19
|
+
export type FunctionKind = 'function' | 'event';
|
|
20
|
+
export interface FunctionInfo {
|
|
21
|
+
readonly id: number;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly line: number;
|
|
24
|
+
readonly col: number;
|
|
25
|
+
readonly kind: FunctionKind;
|
|
26
|
+
/** State name for events; undefined for free functions. */
|
|
27
|
+
readonly state?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface StateInfo {
|
|
30
|
+
readonly id: number;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly line: number;
|
|
33
|
+
readonly col: number;
|
|
34
|
+
}
|
|
35
|
+
export interface CoveragePlan {
|
|
36
|
+
readonly filename: string;
|
|
37
|
+
readonly source: string;
|
|
38
|
+
readonly statements: ReadonlyArray<StatementInfo>;
|
|
39
|
+
readonly branches: ReadonlyArray<BranchInfo>;
|
|
40
|
+
readonly functions: ReadonlyArray<FunctionInfo>;
|
|
41
|
+
readonly states: ReadonlyArray<StateInfo>;
|
|
42
|
+
}
|
|
43
|
+
export interface StatementHit extends StatementInfo {
|
|
44
|
+
readonly hits: number;
|
|
45
|
+
}
|
|
46
|
+
export interface BranchHit extends BranchInfo {
|
|
47
|
+
/**
|
|
48
|
+
* `[trueHits, falseHits]` — count of times the conditional expression
|
|
49
|
+
* evaluated truthy / falsy, respectively. For `if`, true means consequent
|
|
50
|
+
* taken, false means alternate (or implicit-else) taken. For `while` /
|
|
51
|
+
* `for`, true means another iteration started, false means the loop
|
|
52
|
+
* exited. **For `do-while`, the body always runs at least once before
|
|
53
|
+
* the test is evaluated**, so a single-pass do-while produces `[0, 1]`
|
|
54
|
+
* (zero true outcomes, one false outcome that ended the loop) even
|
|
55
|
+
* though the body executed once — body-entered counts live in statement
|
|
56
|
+
* coverage on the body, not branch coverage on the loop.
|
|
57
|
+
*/
|
|
58
|
+
readonly hits: readonly [number, number];
|
|
59
|
+
}
|
|
60
|
+
export interface FunctionHit extends FunctionInfo {
|
|
61
|
+
readonly hits: number;
|
|
62
|
+
}
|
|
63
|
+
export interface StateHit extends StateInfo {
|
|
64
|
+
readonly hits: number;
|
|
65
|
+
}
|
|
66
|
+
export interface CoverageReport {
|
|
67
|
+
readonly filename: string;
|
|
68
|
+
readonly source: string;
|
|
69
|
+
readonly statements: ReadonlyArray<StatementHit>;
|
|
70
|
+
readonly branches: ReadonlyArray<BranchHit>;
|
|
71
|
+
readonly functions: ReadonlyArray<FunctionHit>;
|
|
72
|
+
readonly states: ReadonlyArray<StateHit>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Walks an AST and enumerates every coverable item.
|
|
76
|
+
* Coverage IDs are `loc.offset` — stable across the lifetime of a single
|
|
77
|
+
* parse, unique within a file, and cheap to use as Map keys.
|
|
78
|
+
*/
|
|
79
|
+
export declare function buildCoveragePlan(ast: Ast, filename: string, source: string): CoveragePlan;
|
|
80
|
+
/**
|
|
81
|
+
* Per-script hit counter. Lives on `ScriptState.coverage` when coverage is
|
|
82
|
+
* enabled; otherwise the field is null and hooks short-circuit.
|
|
83
|
+
*
|
|
84
|
+
* Counts are kept in plain Maps keyed by `loc.offset`. State coverage is
|
|
85
|
+
* keyed by state name — state changes name targets, not offsets.
|
|
86
|
+
*/
|
|
87
|
+
export declare class CoverageCollector {
|
|
88
|
+
readonly plan: CoveragePlan;
|
|
89
|
+
private readonly statementHits;
|
|
90
|
+
private readonly branchHits;
|
|
91
|
+
private readonly functionHits;
|
|
92
|
+
private readonly stateHits;
|
|
93
|
+
constructor(plan: CoveragePlan);
|
|
94
|
+
hitStatement(loc: SourceLocation): void;
|
|
95
|
+
hitBranch(loc: SourceLocation, taken: boolean): void;
|
|
96
|
+
hitFunction(loc: SourceLocation): void;
|
|
97
|
+
hitState(name: string): void;
|
|
98
|
+
/** Frozen snapshot suitable for serialization or assertions. */
|
|
99
|
+
snapshot(): CoverageReport;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Merge multiple reports for the same filename into one. Used by the Vitest
|
|
103
|
+
* reporter when the same script is loaded across multiple tests in a run:
|
|
104
|
+
* planes match, hit counts union (sum).
|
|
105
|
+
*
|
|
106
|
+
* Throws if reports disagree on filename or plan shape — that signals a
|
|
107
|
+
* source change mid-run, which should fail loudly rather than be glossed.
|
|
108
|
+
*/
|
|
109
|
+
export declare function mergeReports(reports: ReadonlyArray<CoverageReport>): CoverageReport;
|
|
110
|
+
//# sourceMappingURL=coverage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"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"}
|