@rezi-ui/node 0.1.0-alpha.2 → 0.1.0-alpha.21

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 (53) hide show
  1. package/README.md +20 -6
  2. package/dist/backend/emojiWidthPolicy.d.ts +15 -0
  3. package/dist/backend/emojiWidthPolicy.d.ts.map +1 -0
  4. package/dist/backend/emojiWidthPolicy.js +211 -0
  5. package/dist/backend/emojiWidthPolicy.js.map +1 -0
  6. package/dist/backend/nodeBackend.d.ts +29 -1
  7. package/dist/backend/nodeBackend.d.ts.map +1 -1
  8. package/dist/backend/nodeBackend.js +116 -12
  9. package/dist/backend/nodeBackend.js.map +1 -1
  10. package/dist/backend/nodeBackendInline.d.ts.map +1 -1
  11. package/dist/backend/nodeBackendInline.js +111 -11
  12. package/dist/backend/nodeBackendInline.js.map +1 -1
  13. package/dist/backend/terminalProfile.d.ts +5 -0
  14. package/dist/backend/terminalProfile.d.ts.map +1 -0
  15. package/dist/backend/terminalProfile.js +117 -0
  16. package/dist/backend/terminalProfile.js.map +1 -0
  17. package/dist/image.d.ts +2 -0
  18. package/dist/image.d.ts.map +1 -0
  19. package/dist/image.js +16 -0
  20. package/dist/image.js.map +1 -0
  21. package/dist/index.d.ts +16 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +64 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/repro/index.d.ts +3 -0
  26. package/dist/repro/index.d.ts.map +1 -0
  27. package/dist/repro/index.js +2 -0
  28. package/dist/repro/index.js.map +1 -0
  29. package/dist/repro/recorder.d.ts +31 -0
  30. package/dist/repro/recorder.d.ts.map +1 -0
  31. package/dist/repro/recorder.js +326 -0
  32. package/dist/repro/recorder.js.map +1 -0
  33. package/dist/worker/engineWorker.js +33 -3
  34. package/dist/worker/engineWorker.js.map +1 -1
  35. package/dist/worker/protocol.d.ts +3 -0
  36. package/dist/worker/protocol.d.ts.map +1 -1
  37. package/dist/worker/testShims/invalidPollBytesNative.d.ts +22 -0
  38. package/dist/worker/testShims/invalidPollBytesNative.d.ts.map +1 -0
  39. package/dist/worker/testShims/invalidPollBytesNative.js +65 -0
  40. package/dist/worker/testShims/invalidPollBytesNative.js.map +1 -0
  41. package/package.json +11 -7
  42. package/dist/__e2e__/fixtures/terminal-app.d.ts +0 -2
  43. package/dist/__e2e__/fixtures/terminal-app.d.ts.map +0 -1
  44. package/dist/__e2e__/fixtures/terminal-app.js +0 -42
  45. package/dist/__e2e__/fixtures/terminal-app.js.map +0 -1
  46. package/dist/__e2e__/terminal-render.e2e.test.d.ts +0 -2
  47. package/dist/__e2e__/terminal-render.e2e.test.d.ts.map +0 -1
  48. package/dist/__e2e__/terminal-render.e2e.test.js +0 -125
  49. package/dist/__e2e__/terminal-render.e2e.test.js.map +0 -1
  50. package/dist/__tests__/worker_integration.test.d.ts +0 -2
  51. package/dist/__tests__/worker_integration.test.d.ts.map +0 -1
  52. package/dist/__tests__/worker_integration.test.js +0 -569
  53. package/dist/__tests__/worker_integration.test.js.map +0 -1
@@ -0,0 +1,117 @@
1
+ import { DEFAULT_TERMINAL_PROFILE, terminalProfileFromCaps, } from "@rezi-ui/core";
2
+ function envText(env, key) {
3
+ const value = env[key];
4
+ if (typeof value !== "string")
5
+ return undefined;
6
+ const trimmed = value.trim();
7
+ return trimmed.length > 0 ? trimmed : undefined;
8
+ }
9
+ function envLower(env, key) {
10
+ const value = envText(env, key);
11
+ return value?.toLowerCase();
12
+ }
13
+ function envInt(env, key) {
14
+ const raw = envText(env, key);
15
+ if (!raw)
16
+ return undefined;
17
+ const value = Number.parseInt(raw, 10);
18
+ if (!Number.isFinite(value) || value <= 0)
19
+ return undefined;
20
+ return value;
21
+ }
22
+ function envBool(env, key) {
23
+ const raw = envLower(env, key);
24
+ if (!raw)
25
+ return undefined;
26
+ if (raw === "1" || raw === "true" || raw === "yes" || raw === "on")
27
+ return true;
28
+ if (raw === "0" || raw === "false" || raw === "no" || raw === "off")
29
+ return false;
30
+ return undefined;
31
+ }
32
+ function detectTerminalHints(env) {
33
+ const term = envLower(env, "TERM") ?? "";
34
+ const termProgram = envLower(env, "TERM_PROGRAM");
35
+ const lcTerminal = envLower(env, "LC_TERMINAL");
36
+ const lcTerminalVersion = envText(env, "LC_TERMINAL_VERSION");
37
+ const termProgramVersion = envText(env, "TERM_PROGRAM_VERSION");
38
+ const isKitty = envText(env, "KITTY_WINDOW_ID") !== undefined || term.includes("kitty");
39
+ const isWezTerm = envText(env, "WEZTERM_PANE") !== undefined ||
40
+ envText(env, "WEZTERM_EXECUTABLE") !== undefined ||
41
+ termProgram === "wezterm" ||
42
+ term.includes("wezterm");
43
+ const isIterm2 = envText(env, "ITERM_SESSION_ID") !== undefined ||
44
+ termProgram === "iterm.app" ||
45
+ lcTerminal === "iterm2";
46
+ const isGhostty = envText(env, "GHOSTTY_RESOURCES_DIR") !== undefined ||
47
+ termProgram === "ghostty" ||
48
+ term.includes("ghostty");
49
+ const isWindowsTerminal = envText(env, "WT_SESSION") !== undefined;
50
+ const isXterm = term.includes("xterm");
51
+ const isTmux = envText(env, "TMUX") !== undefined || term.startsWith("tmux");
52
+ let id = "unknown";
53
+ let versionString = "";
54
+ if (isKitty) {
55
+ id = "kitty";
56
+ versionString = envText(env, "KITTY_VERSION") ?? termProgramVersion ?? "";
57
+ }
58
+ else if (isWezTerm) {
59
+ id = "wezterm";
60
+ versionString = envText(env, "WEZTERM_VERSION") ?? termProgramVersion ?? "";
61
+ }
62
+ else if (isIterm2) {
63
+ id = "iterm2";
64
+ versionString = termProgramVersion ?? lcTerminalVersion ?? "";
65
+ }
66
+ else if (isGhostty) {
67
+ id = "ghostty";
68
+ versionString = termProgramVersion ?? "";
69
+ }
70
+ else if (isWindowsTerminal) {
71
+ id = "windows-terminal";
72
+ versionString = envText(env, "WT_VERSION") ?? "";
73
+ }
74
+ else if (isTmux) {
75
+ id = "tmux";
76
+ }
77
+ else if (isXterm) {
78
+ id = "xterm";
79
+ }
80
+ const kittyOverride = envBool(env, "REZI_TERMINAL_SUPPORTS_KITTY");
81
+ const sixelOverride = envBool(env, "REZI_TERMINAL_SUPPORTS_SIXEL");
82
+ const itermOverride = envBool(env, "REZI_TERMINAL_SUPPORTS_ITERM2");
83
+ const osc8Override = envBool(env, "REZI_TERMINAL_SUPPORTS_OSC8");
84
+ const supportsKittyGraphics = kittyOverride ?? (isKitty || isGhostty);
85
+ const supportsSixel = sixelOverride ?? (isWezTerm || term.includes("sixel"));
86
+ const supportsIterm2Images = itermOverride ?? isIterm2;
87
+ const supportsHyperlinks = osc8Override ?? (isKitty || isWezTerm || isGhostty || isIterm2 || isWindowsTerminal || isXterm);
88
+ const cellWidthPx = envInt(env, "REZI_CELL_WIDTH_PX") ?? envInt(env, "ZR_CELL_WIDTH_PX");
89
+ const cellHeightPx = envInt(env, "REZI_CELL_HEIGHT_PX") ?? envInt(env, "ZR_CELL_HEIGHT_PX");
90
+ return Object.freeze({
91
+ id,
92
+ versionString,
93
+ supportsKittyGraphics,
94
+ supportsSixel,
95
+ supportsIterm2Images,
96
+ supportsHyperlinks,
97
+ ...(cellWidthPx === undefined ? {} : { cellWidthPx }),
98
+ ...(cellHeightPx === undefined ? {} : { cellHeightPx }),
99
+ });
100
+ }
101
+ export function terminalProfileFromNodeEnv(caps, env = process.env) {
102
+ const base = terminalProfileFromCaps(caps);
103
+ const hints = detectTerminalHints(env);
104
+ return Object.freeze({
105
+ ...DEFAULT_TERMINAL_PROFILE,
106
+ ...base,
107
+ ...(hints.id ? { id: hints.id } : {}),
108
+ ...(hints.versionString ? { versionString: hints.versionString } : {}),
109
+ ...(hints.cellWidthPx === undefined ? {} : { cellWidthPx: hints.cellWidthPx }),
110
+ ...(hints.cellHeightPx === undefined ? {} : { cellHeightPx: hints.cellHeightPx }),
111
+ supportsKittyGraphics: hints.supportsKittyGraphics ?? base.supportsKittyGraphics,
112
+ supportsSixel: hints.supportsSixel ?? base.supportsSixel,
113
+ supportsIterm2Images: hints.supportsIterm2Images ?? base.supportsIterm2Images,
114
+ supportsHyperlinks: hints.supportsHyperlinks ?? base.supportsHyperlinks,
115
+ });
116
+ }
117
+ //# sourceMappingURL=terminalProfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminalProfile.js","sourceRoot":"","sources":["../../src/backend/terminalProfile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function loadImage(path: string): Uint8Array;
2
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAUlD"}
package/dist/image.js ADDED
@@ -0,0 +1,16 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ const IMAGE_CACHE = new Map();
4
+ export function loadImage(path) {
5
+ if (path.length === 0) {
6
+ throw new TypeError("loadImage(path): path must be a non-empty string");
7
+ }
8
+ const resolvedPath = resolve(path);
9
+ const cached = IMAGE_CACHE.get(resolvedPath);
10
+ if (cached)
11
+ return cached;
12
+ const bytes = new Uint8Array(readFileSync(resolvedPath));
13
+ IMAGE_CACHE.set(resolvedPath, bytes);
14
+ return bytes;
15
+ }
16
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../src/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;AAElD,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,SAAS,CAAC,kDAAkD,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC7C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC;IACzD,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC;AACf,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,21 @@
1
+ import { type App, type AppConfig, type Theme, type ThemeDefinition } from "@rezi-ui/core";
1
2
  import { type NodeBackend, type NodeBackendConfig } from "./backend/nodeBackend.js";
3
+ import { createReproRecorder } from "./repro/index.js";
2
4
  export type { NodeBackendConfig };
3
5
  export type { NodeBackend };
6
+ export type { CreateReproRecorderOptions, ReproRecorder, ReproRecorderBackendCapsOverrides, ReproRecorderBounds, ReproRecorderBuildResult, } from "./repro/index.js";
7
+ export { createReproRecorder };
8
+ export { loadImage } from "./image.js";
9
+ export type NodeAppConfig = Readonly<AppConfig & Omit<NodeBackendConfig, "fpsCap" | "maxEventBytes" | "useDrawlistV2">>;
10
+ export type CreateNodeAppOptions<S> = Readonly<{
11
+ initialState: S;
12
+ config?: NodeAppConfig;
13
+ theme?: Theme | ThemeDefinition;
14
+ }>;
15
+ export declare function createNodeApp<S>(opts: CreateNodeAppOptions<S>): App<S>;
16
+ /**
17
+ * @deprecated Prefer createNodeApp() for normal Node/Bun apps.
18
+ * createNodeBackend() remains available for advanced runtime composition.
19
+ */
4
20
  export declare function createNodeBackend(config?: NodeBackendConfig): NodeBackend;
5
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,iBAAsB,GAAG,WAAW,CAE7E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,eAAe,EAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EAEvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,CAAC;AAC5B,YAAY,EACV,0BAA0B,EAC1B,aAAa,EACb,iCAAiC,EACjC,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,aAAa,GAAG,QAAQ,CAClC,SAAS,GAAG,IAAI,CAAC,iBAAiB,EAAE,QAAQ,GAAG,eAAe,GAAG,eAAe,CAAC,CAClF,CAAC;AAEF,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,QAAQ,CAAC;IAC7C,YAAY,EAAE,CAAC,CAAC;IAChB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC;CACjC,CAAC,CAAC;AAgDH,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAUtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,iBAAsB,GAAG,WAAW,CAE7E"}
package/dist/index.js CHANGED
@@ -1,4 +1,68 @@
1
+ import { createApp, } from "@rezi-ui/core";
1
2
  import { createNodeBackendInternal, } from "./backend/nodeBackend.js";
3
+ import { createReproRecorder } from "./repro/index.js";
4
+ export { createReproRecorder };
5
+ export { loadImage } from "./image.js";
6
+ function toAppConfig(config) {
7
+ if (config === undefined)
8
+ return undefined;
9
+ return {
10
+ ...(config.fpsCap !== undefined ? { fpsCap: config.fpsCap } : {}),
11
+ ...(config.maxEventBytes !== undefined ? { maxEventBytes: config.maxEventBytes } : {}),
12
+ ...(config.maxDrawlistBytes !== undefined ? { maxDrawlistBytes: config.maxDrawlistBytes } : {}),
13
+ ...(config.useV2Cursor !== undefined ? { useV2Cursor: config.useV2Cursor } : {}),
14
+ ...(config.drawlistValidateParams !== undefined
15
+ ? { drawlistValidateParams: config.drawlistValidateParams }
16
+ : {}),
17
+ ...(config.drawlistReuseOutputBuffer !== undefined
18
+ ? { drawlistReuseOutputBuffer: config.drawlistReuseOutputBuffer }
19
+ : {}),
20
+ ...(config.drawlistEncodedStringCacheCap !== undefined
21
+ ? { drawlistEncodedStringCacheCap: config.drawlistEncodedStringCacheCap }
22
+ : {}),
23
+ ...(config.maxFramesInFlight !== undefined
24
+ ? { maxFramesInFlight: config.maxFramesInFlight }
25
+ : {}),
26
+ ...(config.internal_onRender !== undefined
27
+ ? { internal_onRender: config.internal_onRender }
28
+ : {}),
29
+ ...(config.internal_onLayout !== undefined
30
+ ? { internal_onLayout: config.internal_onLayout }
31
+ : {}),
32
+ };
33
+ }
34
+ function toBackendConfig(config) {
35
+ if (config === undefined)
36
+ return {};
37
+ return {
38
+ ...(config.executionMode !== undefined ? { executionMode: config.executionMode } : {}),
39
+ ...(config.fpsCap !== undefined ? { fpsCap: config.fpsCap } : {}),
40
+ ...(config.maxEventBytes !== undefined ? { maxEventBytes: config.maxEventBytes } : {}),
41
+ ...(config.drawlistVersion !== undefined ? { drawlistVersion: config.drawlistVersion } : {}),
42
+ ...(config.frameTransport !== undefined ? { frameTransport: config.frameTransport } : {}),
43
+ ...(config.frameSabSlotCount !== undefined
44
+ ? { frameSabSlotCount: config.frameSabSlotCount }
45
+ : {}),
46
+ ...(config.frameSabSlotBytes !== undefined
47
+ ? { frameSabSlotBytes: config.frameSabSlotBytes }
48
+ : {}),
49
+ ...(config.nativeConfig !== undefined ? { nativeConfig: config.nativeConfig } : {}),
50
+ };
51
+ }
52
+ export function createNodeApp(opts) {
53
+ const appConfig = toAppConfig(opts.config);
54
+ const backend = createNodeBackend(toBackendConfig(opts.config));
55
+ return createApp({
56
+ backend,
57
+ initialState: opts.initialState,
58
+ ...(appConfig !== undefined ? { config: appConfig } : {}),
59
+ ...(opts.theme !== undefined ? { theme: opts.theme } : {}),
60
+ });
61
+ }
62
+ /**
63
+ * @deprecated Prefer createNodeApp() for normal Node/Bun apps.
64
+ * createNodeBackend() remains available for advanced runtime composition.
65
+ */
2
66
  export function createNodeBackend(config = {}) {
3
67
  return createNodeBackendInternal({ config });
4
68
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAKlC,MAAM,UAAU,iBAAiB,CAAC,SAA4B,EAAE;IAC9D,OAAO,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export type { CreateReproRecorderOptions, ReproRecorder, ReproRecorderBackendCapsOverrides, ReproRecorderBounds, ReproRecorderBuildResult, } from "./recorder.js";
2
+ export { createReproRecorder } from "./recorder.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repro/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,0BAA0B,EAC1B,aAAa,EACb,iCAAiC,EACjC,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createReproRecorder } from "./recorder.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repro/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { type ReproBundleV1, type ReproEventCapture, type RuntimeBackend, type TerminalCaps } from "@rezi-ui/core";
2
+ export type ReproRecorderBounds = Readonly<{
3
+ maxBatches?: number;
4
+ maxEvents?: number;
5
+ maxBytes?: number;
6
+ }>;
7
+ export type ReproRecorderBackendCapsOverrides = Readonly<{
8
+ maxEventBytes?: number;
9
+ fpsCap?: number;
10
+ cursorProtocolVersion?: 1 | 2;
11
+ }>;
12
+ export type CreateReproRecorderOptions = Readonly<{
13
+ bounds?: ReproRecorderBounds;
14
+ backendCaps?: ReproRecorderBackendCapsOverrides;
15
+ terminalCaps?: TerminalCaps | null;
16
+ clock?: () => number;
17
+ }>;
18
+ export type ReproRecorderBuildResult = Readonly<{
19
+ bundle: ReproBundleV1;
20
+ bytes: Uint8Array;
21
+ }>;
22
+ export type ReproRecorder = Readonly<{
23
+ backend: RuntimeBackend;
24
+ buildBundle: () => Promise<ReproBundleV1>;
25
+ buildBytes: () => Promise<Uint8Array>;
26
+ build: () => Promise<ReproRecorderBuildResult>;
27
+ snapshot: () => ReproEventCapture;
28
+ reset: () => void;
29
+ }>;
30
+ export declare function createReproRecorder(backend: RuntimeBackend, options?: CreateReproRecorderOptions): ReproRecorder;
31
+ //# sourceMappingURL=recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/repro/recorder.ts"],"names":[],"mappings":"AACA,OAAO,EAaL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAKtB,KAAK,cAAc,EACnB,KAAK,YAAY,EAGlB,MAAM,eAAe,CAAC;AAQvB,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,MAAM,MAAM,iCAAiC,GAAG,QAAQ,CAAC;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qBAAqB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,WAAW,CAAC,EAAE,iCAAiC,CAAC;IAChD,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB,CAAC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;CACnB,CAAC,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,KAAK,EAAE,MAAM,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC/C,QAAQ,EAAE,MAAM,iBAAiB,CAAC;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC,CAAC;AAyLH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,0BAA+B,GACvC,aAAa,CAiMf"}
@@ -0,0 +1,326 @@
1
+ import { performance } from "node:perf_hooks";
2
+ import { BACKEND_DRAWLIST_V2_MARKER, BACKEND_FPS_CAP_MARKER, BACKEND_MAX_EVENT_BYTES_MARKER, REPRO_BUNDLE_SCHEMA_V1, REPRO_EVENT_CAPTURE_ORDERING_POLL, REPRO_EVENT_CAPTURE_TIMING_STEP_DELTA_MS, REPRO_EVENT_CAPTURE_TRUNCATION_MODE_DROP_TAIL_BATCH, REPRO_TIMING_CLOCK_MONOTONIC_MS, REPRO_TIMING_MODEL_KIND_DETERMINISTIC, REPRO_TIMING_REPLAY_STRATEGY_RECORDED_DELTA, REPRO_TIMING_UNIT_MS, exportReproBundleBytes, parseEventBatchV1, } from "@rezi-ui/core";
3
+ const DEFAULT_MAX_BATCHES = 256;
4
+ const DEFAULT_MAX_EVENTS = 8192;
5
+ const DEFAULT_MAX_BYTES = 4 * 1024 * 1024;
6
+ const DEFAULT_MAX_EVENT_BYTES = 1024 * 1024;
7
+ const DEFAULT_FPS_CAP = 60;
8
+ function normalizeNonNegativeInteger(value, fallback) {
9
+ if (typeof value !== "number")
10
+ return fallback;
11
+ if (!Number.isFinite(value))
12
+ return fallback;
13
+ if (!Number.isInteger(value))
14
+ return fallback;
15
+ if (value < 0)
16
+ return fallback;
17
+ return value;
18
+ }
19
+ function normalizePositiveInteger(value, fallback) {
20
+ if (typeof value !== "number")
21
+ return fallback;
22
+ if (!Number.isFinite(value))
23
+ return fallback;
24
+ if (!Number.isInteger(value))
25
+ return fallback;
26
+ if (value <= 0)
27
+ return fallback;
28
+ return value;
29
+ }
30
+ function normalizeClockSample(value) {
31
+ if (!Number.isFinite(value))
32
+ return 0;
33
+ const floored = Math.floor(value);
34
+ if (floored < 0)
35
+ return 0;
36
+ return floored;
37
+ }
38
+ function toLowerHex(bytes) {
39
+ const out = new Array(bytes.byteLength);
40
+ for (let i = 0; i < bytes.byteLength; i++) {
41
+ out[i] = bytes[i]?.toString(16).padStart(2, "0") ?? "00";
42
+ }
43
+ return out.join("");
44
+ }
45
+ function cloneTerminalCaps(caps) {
46
+ if (caps === null)
47
+ return null;
48
+ return {
49
+ colorMode: caps.colorMode,
50
+ supportsMouse: caps.supportsMouse,
51
+ supportsBracketedPaste: caps.supportsBracketedPaste,
52
+ supportsFocusEvents: caps.supportsFocusEvents,
53
+ supportsOsc52: caps.supportsOsc52,
54
+ supportsSyncUpdate: caps.supportsSyncUpdate,
55
+ supportsScrollRegion: caps.supportsScrollRegion,
56
+ supportsCursorShape: caps.supportsCursorShape,
57
+ supportsOutputWaitWritable: caps.supportsOutputWaitWritable,
58
+ supportsUnderlineStyles: caps.supportsUnderlineStyles,
59
+ supportsColoredUnderlines: caps.supportsColoredUnderlines,
60
+ supportsHyperlinks: caps.supportsHyperlinks,
61
+ sgrAttrsSupported: caps.sgrAttrsSupported,
62
+ };
63
+ }
64
+ function buildBackendCapsSnapshot(backend, bounds, overrides) {
65
+ const rec = backend;
66
+ const markerMaxEventBytes = rec[BACKEND_MAX_EVENT_BYTES_MARKER];
67
+ const markerFpsCap = rec[BACKEND_FPS_CAP_MARKER];
68
+ const markerUseV2 = rec[BACKEND_DRAWLIST_V2_MARKER] === true;
69
+ const maxEventBytes = normalizePositiveInteger(overrides?.maxEventBytes ?? markerMaxEventBytes, bounds.maxBytes > 0 ? bounds.maxBytes : DEFAULT_MAX_EVENT_BYTES);
70
+ const fpsCap = normalizePositiveInteger(overrides?.fpsCap ?? markerFpsCap, DEFAULT_FPS_CAP);
71
+ const cursorProtocolVersion = overrides?.cursorProtocolVersion === 1 || overrides?.cursorProtocolVersion === 2
72
+ ? overrides.cursorProtocolVersion
73
+ : markerUseV2
74
+ ? 2
75
+ : 1;
76
+ return {
77
+ maxEventBytes,
78
+ fpsCap,
79
+ cursorProtocolVersion,
80
+ };
81
+ }
82
+ function createMutableState() {
83
+ return {
84
+ batches: [],
85
+ capturedBatches: 0,
86
+ capturedEvents: 0,
87
+ capturedBytes: 0,
88
+ omittedBatches: 0,
89
+ omittedEvents: 0,
90
+ omittedBytes: 0,
91
+ runtimeDroppedBatches: 0,
92
+ truncated: false,
93
+ truncationReason: null,
94
+ firstOmittedStep: null,
95
+ baseTimeMs: null,
96
+ lastCapturedTimeMs: null,
97
+ };
98
+ }
99
+ function buildEventCaptureSnapshot(state, bounds) {
100
+ return {
101
+ ordering: REPRO_EVENT_CAPTURE_ORDERING_POLL,
102
+ timing: REPRO_EVENT_CAPTURE_TIMING_STEP_DELTA_MS,
103
+ bounds: {
104
+ maxBatches: bounds.maxBatches,
105
+ maxEvents: bounds.maxEvents,
106
+ maxBytes: bounds.maxBytes,
107
+ },
108
+ totals: {
109
+ capturedBatches: state.capturedBatches,
110
+ capturedEvents: state.capturedEvents,
111
+ capturedBytes: state.capturedBytes,
112
+ runtimeDroppedBatches: state.runtimeDroppedBatches,
113
+ omittedBatches: state.omittedBatches,
114
+ omittedEvents: state.omittedEvents,
115
+ omittedBytes: state.omittedBytes,
116
+ },
117
+ truncation: {
118
+ mode: REPRO_EVENT_CAPTURE_TRUNCATION_MODE_DROP_TAIL_BATCH,
119
+ truncated: state.truncated,
120
+ reason: state.truncationReason,
121
+ firstOmittedStep: state.firstOmittedStep,
122
+ },
123
+ batches: state.batches.slice(),
124
+ };
125
+ }
126
+ function parseBatchMetadata(bytes) {
127
+ const parsed = parseEventBatchV1(bytes);
128
+ if (!parsed.ok) {
129
+ return {
130
+ eventCount: 0,
131
+ resizeEvents: [],
132
+ };
133
+ }
134
+ const events = parsed.value.events;
135
+ const resizeEvents = [];
136
+ for (let i = 0; i < events.length; i++) {
137
+ const event = events[i];
138
+ if (event?.kind !== "resize")
139
+ continue;
140
+ resizeEvents.push({
141
+ eventIndex: i,
142
+ cols: event.cols,
143
+ rows: event.rows,
144
+ timeMs: normalizeClockSample(event.timeMs),
145
+ });
146
+ }
147
+ return {
148
+ eventCount: events.length,
149
+ resizeEvents,
150
+ };
151
+ }
152
+ function copyBatchBytes(batch) {
153
+ const out = new Uint8Array(batch.bytes.byteLength);
154
+ out.set(batch.bytes);
155
+ return out;
156
+ }
157
+ export function createReproRecorder(backend, options = {}) {
158
+ const bounds = {
159
+ maxBatches: normalizeNonNegativeInteger(options.bounds?.maxBatches, DEFAULT_MAX_BATCHES),
160
+ maxEvents: normalizeNonNegativeInteger(options.bounds?.maxEvents, DEFAULT_MAX_EVENTS),
161
+ maxBytes: normalizeNonNegativeInteger(options.bounds?.maxBytes, DEFAULT_MAX_BYTES),
162
+ };
163
+ const backendCaps = buildBackendCapsSnapshot(backend, bounds, options.backendCaps);
164
+ const now = options.clock ?? (() => performance.now());
165
+ let cachedTerminalCaps = options.terminalCaps !== undefined ? cloneTerminalCaps(options.terminalCaps) : undefined;
166
+ const state = createMutableState();
167
+ const originalPollEvents = backend.pollEvents.bind(backend);
168
+ const originalGetCaps = backend.getCaps.bind(backend);
169
+ async function resolveTerminalCaps() {
170
+ if (cachedTerminalCaps !== undefined) {
171
+ return cloneTerminalCaps(cachedTerminalCaps);
172
+ }
173
+ try {
174
+ const caps = await originalGetCaps();
175
+ cachedTerminalCaps = cloneTerminalCaps(caps);
176
+ return cloneTerminalCaps(cachedTerminalCaps);
177
+ }
178
+ catch {
179
+ cachedTerminalCaps = null;
180
+ return null;
181
+ }
182
+ }
183
+ function appendOmittedBatch(eventCount, byteLength) {
184
+ state.omittedBatches += 1;
185
+ state.omittedEvents += eventCount;
186
+ state.omittedBytes += byteLength;
187
+ }
188
+ function markTruncated(reason) {
189
+ if (state.truncated)
190
+ return;
191
+ state.truncated = true;
192
+ state.truncationReason = reason;
193
+ state.firstOmittedStep = state.capturedBatches;
194
+ }
195
+ function recordCapturedBatch(byteLength, bytesHex, droppedBatches, eventCount, resizeEvents) {
196
+ const nowMs = normalizeClockSample(now());
197
+ if (state.baseTimeMs === null) {
198
+ state.baseTimeMs = nowMs;
199
+ }
200
+ const deltaMs = state.lastCapturedTimeMs === null ? 0 : Math.max(0, nowMs - state.lastCapturedTimeMs);
201
+ state.lastCapturedTimeMs = nowMs;
202
+ state.batches.push({
203
+ step: state.capturedBatches,
204
+ deltaMs,
205
+ byteLength,
206
+ bytesHex,
207
+ eventCount,
208
+ droppedBatches,
209
+ resizeEvents: resizeEvents.slice(),
210
+ });
211
+ state.capturedBatches += 1;
212
+ state.capturedEvents += eventCount;
213
+ state.capturedBytes += byteLength;
214
+ }
215
+ function observeBatch(bytes, droppedBatches) {
216
+ const byteLength = bytes.byteLength;
217
+ const { eventCount, resizeEvents } = parseBatchMetadata(bytes);
218
+ state.runtimeDroppedBatches += droppedBatches;
219
+ if (state.truncated) {
220
+ appendOmittedBatch(eventCount, byteLength);
221
+ return;
222
+ }
223
+ if (state.capturedBatches >= bounds.maxBatches) {
224
+ markTruncated("max-batches");
225
+ appendOmittedBatch(eventCount, byteLength);
226
+ return;
227
+ }
228
+ if (state.capturedEvents + eventCount > bounds.maxEvents) {
229
+ markTruncated("max-events");
230
+ appendOmittedBatch(eventCount, byteLength);
231
+ return;
232
+ }
233
+ if (state.capturedBytes + byteLength > bounds.maxBytes) {
234
+ markTruncated("max-bytes");
235
+ appendOmittedBatch(eventCount, byteLength);
236
+ return;
237
+ }
238
+ recordCapturedBatch(byteLength, toLowerHex(bytes), droppedBatches, eventCount, resizeEvents);
239
+ }
240
+ const wrapped = Object.create(Object.getPrototypeOf(backend));
241
+ Object.defineProperties(wrapped, Object.getOwnPropertyDescriptors(backend));
242
+ Object.defineProperties(wrapped, {
243
+ pollEvents: {
244
+ value: async () => {
245
+ const batch = await originalPollEvents();
246
+ observeBatch(copyBatchBytes(batch), batch.droppedBatches);
247
+ return batch;
248
+ },
249
+ writable: false,
250
+ enumerable: true,
251
+ configurable: true,
252
+ },
253
+ getCaps: {
254
+ value: async () => {
255
+ const caps = await originalGetCaps();
256
+ cachedTerminalCaps = cloneTerminalCaps(caps);
257
+ return caps;
258
+ },
259
+ writable: false,
260
+ enumerable: true,
261
+ configurable: true,
262
+ },
263
+ });
264
+ async function buildBundle() {
265
+ const terminalCaps = await resolveTerminalCaps();
266
+ const eventCapture = buildEventCaptureSnapshot(state, bounds);
267
+ return {
268
+ schema: REPRO_BUNDLE_SCHEMA_V1,
269
+ captureConfig: {
270
+ captureRawEvents: true,
271
+ captureDrawlistBytes: false,
272
+ maxEventBytes: backendCaps.maxEventBytes,
273
+ maxDrawlistBytes: 0,
274
+ maxFrames: bounds.maxBatches,
275
+ fpsCap: backendCaps.fpsCap,
276
+ cursorProtocolVersion: backendCaps.cursorProtocolVersion,
277
+ },
278
+ capsSnapshot: {
279
+ terminalCaps,
280
+ backendCaps,
281
+ },
282
+ timingModel: {
283
+ kind: REPRO_TIMING_MODEL_KIND_DETERMINISTIC,
284
+ clock: REPRO_TIMING_CLOCK_MONOTONIC_MS,
285
+ replayStrategy: REPRO_TIMING_REPLAY_STRATEGY_RECORDED_DELTA,
286
+ timeUnit: REPRO_TIMING_UNIT_MS,
287
+ baseTimeMs: state.baseTimeMs ?? 0,
288
+ },
289
+ eventCapture,
290
+ };
291
+ }
292
+ async function buildBytes() {
293
+ return exportReproBundleBytes(await buildBundle());
294
+ }
295
+ async function build() {
296
+ const bundle = await buildBundle();
297
+ return {
298
+ bundle,
299
+ bytes: exportReproBundleBytes(bundle),
300
+ };
301
+ }
302
+ function reset() {
303
+ state.batches.length = 0;
304
+ state.capturedBatches = 0;
305
+ state.capturedEvents = 0;
306
+ state.capturedBytes = 0;
307
+ state.omittedBatches = 0;
308
+ state.omittedEvents = 0;
309
+ state.omittedBytes = 0;
310
+ state.runtimeDroppedBatches = 0;
311
+ state.truncated = false;
312
+ state.truncationReason = null;
313
+ state.firstOmittedStep = null;
314
+ state.baseTimeMs = null;
315
+ state.lastCapturedTimeMs = null;
316
+ }
317
+ return {
318
+ backend: wrapped,
319
+ buildBundle,
320
+ buildBytes,
321
+ build,
322
+ snapshot: () => buildEventCaptureSnapshot(state, bounds),
323
+ reset,
324
+ };
325
+ }
326
+ //# sourceMappingURL=recorder.js.map