@ricsam/r5d-browser 0.0.137 → 0.0.139

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 (44) hide show
  1. package/README.md +7 -33
  2. package/dist/cjs/package.json +1 -1
  3. package/dist/mjs/browser-input.mjs +56 -1
  4. package/dist/mjs/cli-options.mjs +1 -0
  5. package/dist/mjs/main.mjs +25 -396
  6. package/dist/mjs/package.json +1 -1
  7. package/dist/mjs/personal-diagnostics.mjs +24 -0
  8. package/dist/mjs/personal-main.mjs +159 -0
  9. package/dist/mjs/personal-port-forward.mjs +183 -0
  10. package/dist/mjs/personal-relay-client.mjs +33 -0
  11. package/dist/mjs/personal-relay-shutdown.mjs +46 -0
  12. package/dist/mjs/runtime/browser-executor.mjs +11 -0
  13. package/dist/mjs/runtime/chromium-factory.mjs +101 -0
  14. package/dist/mjs/runtime/ipc.mjs +128 -0
  15. package/dist/mjs/runtime/isolated-root.mjs +53 -0
  16. package/dist/mjs/runtime/keeper.mjs +169 -0
  17. package/dist/mjs/runtime/ledger.mjs +193 -0
  18. package/dist/mjs/runtime/main.mjs +105 -0
  19. package/dist/mjs/runtime/private-paths.mjs +48 -0
  20. package/dist/mjs/runtime/protocol.mjs +72 -0
  21. package/dist/types/browser-input.d.ts +4 -0
  22. package/dist/types/cli-options.d.ts +1 -0
  23. package/dist/types/personal-diagnostics.d.ts +13 -0
  24. package/dist/types/personal-main.d.ts +9 -0
  25. package/dist/types/personal-port-forward.d.ts +45 -0
  26. package/dist/types/personal-relay-client.d.ts +51 -0
  27. package/dist/types/personal-relay-shutdown.d.ts +19 -0
  28. package/dist/types/runtime/chromium-factory.d.ts +25 -0
  29. package/dist/types/runtime/fixtures/counter-main.d.ts +1 -0
  30. package/dist/types/runtime/fixtures/counter-runtime.d.ts +6 -2
  31. package/dist/types/runtime/isolated-root.d.ts +12 -0
  32. package/dist/types/runtime/main.d.ts +20 -13
  33. package/dist/types/runtime/private-paths.d.ts +4 -0
  34. package/package.json +6 -5
  35. package/dist/cjs/browser-input.cjs +0 -87
  36. package/dist/cjs/browser-runtime.cjs +0 -708
  37. package/dist/cjs/chrome-launcher.cjs +0 -701
  38. package/dist/cjs/cli-options.cjs +0 -95
  39. package/dist/cjs/main.cjs +0 -427
  40. package/dist/cjs/password-safe-snapshot.cjs +0 -150
  41. package/dist/cjs/port-forward-manager.cjs +0 -233
  42. package/dist/cjs/upload-store.cjs +0 -136
  43. package/dist/mjs/port-forward-manager.mjs +0 -199
  44. package/dist/types/port-forward-manager.d.ts +0 -23
@@ -0,0 +1,9 @@
1
+ import type { BrowserCliOptions } from "./cli-options";
2
+ export declare function personalBrowserConnection(options: BrowserCliOptions): {
3
+ origin: string;
4
+ token: string;
5
+ };
6
+ /** Keep Chrome's OS environment intact while isolating r5d state per origin. */
7
+ export declare function personalBrowserStateDirectory(origin: string, rootPath?: string): string;
8
+ /** The locally retained keeper, profile and ledger outlive every web reconnect. */
9
+ export declare function startPersonalBrowser(options: BrowserCliOptions, version: string): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import type { PersonalBrowserObserver } from "./personal-diagnostics";
2
+ export type ForwardRequest = {
3
+ forwardId: string;
4
+ streamId: string;
5
+ requestId: string;
6
+ command: {
7
+ method: "connect" | "write" | "read" | "close";
8
+ offset?: number;
9
+ after?: number;
10
+ base64?: string;
11
+ end?: boolean;
12
+ };
13
+ };
14
+ export type ForwardCall = (request: ForwardRequest) => Promise<any>;
15
+ export declare class PersonalForwardResponseError extends Error {
16
+ readonly status: number;
17
+ readonly code?: string | undefined;
18
+ constructor(status: number, message: string, code?: string | undefined);
19
+ }
20
+ /** Local loopback sockets outlive every HTTP relay/web connection. Each byte
21
+ * operation waits for its immutable acknowledgement before advancing offsets. */
22
+ export declare class PersonalPortForwardManager {
23
+ private readonly call;
24
+ private readonly observer?;
25
+ private active;
26
+ private failures;
27
+ private queue;
28
+ private stopping;
29
+ constructor(call: ForwardCall, observer?: PersonalBrowserObserver | undefined);
30
+ private observe;
31
+ list(): {
32
+ forwardId: string;
33
+ ready: boolean;
34
+ activeConnections: number;
35
+ lastError: {
36
+ error: string;
37
+ at: string;
38
+ } | null;
39
+ }[];
40
+ reconcile(raw: unknown): Promise<void>;
41
+ private start;
42
+ private stop;
43
+ private accept;
44
+ close(): Promise<void>;
45
+ }
@@ -0,0 +1,51 @@
1
+ import { BrowserKeeper } from "./runtime/keeper";
2
+ import { type BrowserReceipt } from "./runtime/protocol";
3
+ import { z } from "zod";
4
+ export declare const PersonalBrowserAction: z.ZodObject<{
5
+ id: z.ZodString;
6
+ requestHash: z.ZodString;
7
+ request: z.ZodObject<{
8
+ action: z.ZodEnum<{
9
+ list_tabs: "list_tabs";
10
+ list_downloads: "list_downloads";
11
+ get_download: "get_download";
12
+ open_tab: "open_tab";
13
+ close_tab: "close_tab";
14
+ navigate: "navigate";
15
+ set_viewport: "set_viewport";
16
+ read_page: "read_page";
17
+ screenshot: "screenshot";
18
+ move_mouse: "move_mouse";
19
+ mouse_click: "mouse_click";
20
+ scroll: "scroll";
21
+ wait_for: "wait_for";
22
+ form_input: "form_input";
23
+ keyboard: "keyboard";
24
+ keyboard_type: "keyboard_type";
25
+ run_js: "run_js";
26
+ upload_begin: "upload_begin";
27
+ upload_chunk: "upload_chunk";
28
+ upload_attach: "upload_attach";
29
+ upload_abort: "upload_abort";
30
+ }>;
31
+ input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
32
+ }, z.core.$strict>;
33
+ }, z.core.$strict>;
34
+ /** Network replacement never disposes this keeper. Its ledger decides whether an
35
+ * action ran; polling the same server queue item cannot replay a browser effect. */
36
+ export declare class PersonalBrowserProcessor {
37
+ private readonly keeper;
38
+ readonly identity: {
39
+ installationId: string;
40
+ userId: string;
41
+ instanceId: string;
42
+ };
43
+ private readonly nextEpoch?;
44
+ private epoch;
45
+ constructor(keeper: BrowserKeeper, identity: {
46
+ installationId: string;
47
+ userId: string;
48
+ instanceId: string;
49
+ }, nextEpoch?: (() => number) | undefined);
50
+ execute(raw: unknown): Promise<BrowserReceipt>;
51
+ }
@@ -0,0 +1,19 @@
1
+ type RelayAction = {
2
+ id: string;
3
+ requestHash: string;
4
+ };
5
+ export type PersonalBrowserAcknowledgement = {
6
+ id: string;
7
+ requestHash: string;
8
+ state: "completed" | "unknown";
9
+ result: unknown;
10
+ };
11
+ /** Shutdown cancels queue observation, never an admitted browser effect or its receipt. */
12
+ export declare class PersonalBrowserRelayShutdown {
13
+ private readonly polls;
14
+ get stopping(): boolean;
15
+ get pollSignal(): AbortSignal;
16
+ stop(): void;
17
+ dispatch<T extends RelayAction>(actions: readonly T[], execute: (action: T) => Promise<unknown>, acknowledge: (receipt: PersonalBrowserAcknowledgement) => Promise<unknown>): Promise<void>;
18
+ }
19
+ export {};
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+ import type { BrowserExecutor } from "./keeper";
3
+ /** Declarative built-in factory approval, NOT an arbitrary JS module or Chromium argument escape hatch. */
4
+ export declare const ChromiumFactoryApproval: z.ZodObject<{
5
+ kind: z.ZodLiteral<"isolated-chromium-v1">;
6
+ executablePath: z.ZodString;
7
+ allowedOrigins: z.ZodArray<z.ZodString>;
8
+ }, z.core.$strict>;
9
+ export type ChromiumFactoryApproval = z.infer<typeof ChromiumFactoryApproval>;
10
+ export declare function loadApprovedChromiumFactory(filename: string, sha256: string): ChromiumFactoryApproval;
11
+ export type ChromiumKeeperIdentity = {
12
+ runId: string;
13
+ browserPid: number;
14
+ keeperPid: number;
15
+ profile: string;
16
+ downloads: string;
17
+ uploads: string;
18
+ };
19
+ export declare function createIsolatedChromiumRuntime(input: {
20
+ runs: string;
21
+ approval: ChromiumFactoryApproval;
22
+ }): Promise<{
23
+ executor: BrowserExecutor;
24
+ identity: ChromiumKeeperIdentity;
25
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,7 @@
1
- import type { BrowserKeeperRuntimeFactory } from "../main";
1
+ import type { BrowserExecutor } from "../keeper";
2
2
  /** Offline subprocess proof. No Chrome, network, profiles or user resources. */
3
- export declare const createBrowserKeeperRuntime: BrowserKeeperRuntimeFactory;
3
+ export declare const createBrowserKeeperRuntime: ({ directory }: {
4
+ directory: string;
5
+ }) => Promise<{
6
+ executor: BrowserExecutor;
7
+ }>;
@@ -0,0 +1,12 @@
1
+ export declare function isolatedBrowserRoot(root: string, installationId: string, userId: string): {
2
+ ledger: string;
3
+ runs: string;
4
+ };
5
+ export declare function freshBrowserRun(runs: string): {
6
+ id: string;
7
+ directory: string;
8
+ profile: string;
9
+ downloads: string;
10
+ uploads: string;
11
+ home: string;
12
+ };
@@ -1,16 +1,23 @@
1
- import { type BrowserExecutor } from "./keeper";
2
- export type BrowserKeeperRuntimeFactory = (input: {
3
- installationId: string;
4
- userId: string;
5
- directory: string;
6
- }) => Promise<{
7
- executor: BrowserExecutor;
8
- dispose?: () => Promise<void>;
9
- }>;
10
- /**
11
- * Explicit, private, standalone launch surface. runtimeModule is trusted operator code, not a wire field.
12
- * It must export createBrowserKeeperRuntime, constructing browserRuntimeExecutor(runtime) INSIDE this process.
13
- */
1
+ import { z } from "zod";
2
+ import { type ChromiumKeeperIdentity } from "./chromium-factory";
3
+ export declare const BrowserKeeperConfig: z.ZodObject<{
4
+ installationId: z.ZodString;
5
+ userId: z.ZodString;
6
+ instanceId: z.ZodString;
7
+ releaseId: z.ZodString;
8
+ root: z.ZodString;
9
+ factory: z.ZodObject<{
10
+ approvalPath: z.ZodString;
11
+ sha256: z.ZodString;
12
+ }, z.core.$strict>;
13
+ adapters: z.ZodArray<z.ZodObject<{
14
+ ownerId: z.ZodString;
15
+ token: z.ZodString;
16
+ }, z.core.$strict>>;
17
+ }, z.core.$strict>;
18
+ /** Only the built-in isolated REAL Chromium factory is reachable from this startup boundary. */
14
19
  export declare function startConfiguredBrowserKeeper(configPath: string): Promise<{
20
+ socketPath: string;
21
+ identity: ChromiumKeeperIdentity;
15
22
  close(): Promise<void>;
16
23
  }>;
@@ -0,0 +1,4 @@
1
+ /** Reject symlink ancestors, non-canonical paths and writable-by-other-user ancestors. */
2
+ export declare function assertPrivatePath(filename: string, kind: "directory" | "file", immutable?: boolean): void;
3
+ export declare function readPrivateFile(filename: string, maximumBytes: number, immutable?: boolean): Buffer;
4
+ export declare function makePrivateDirectory(directory: string): void;
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@ricsam/r5d-browser",
3
- "version": "0.0.137",
3
+ "version": "0.0.139",
4
4
  "type": "module",
5
- "main": "./dist/cjs/main.cjs",
5
+ "main": "./dist/mjs/main.mjs",
6
6
  "module": "./dist/mjs/main.mjs",
7
7
  "types": "./dist/types/main.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
10
  "types": "./dist/types/main.d.ts",
11
11
  "import": "./dist/mjs/main.mjs",
12
- "require": "./dist/cjs/main.cjs"
12
+ "default": "./dist/mjs/main.mjs"
13
13
  }
14
14
  },
15
15
  "repository": {
@@ -18,11 +18,12 @@
18
18
  "directory": "packages/r5d-browser"
19
19
  },
20
20
  "bin": {
21
- "r5d-browser": "dist/cjs/main.cjs"
21
+ "r5d-browser": "dist/mjs/main.mjs"
22
22
  },
23
23
  "dependencies": {
24
- "@ricsam/r5d-api": "^0.0.137",
24
+ "@ricsam/r5d-api": "^0.0.139",
25
25
  "playwright-core": "1.62.1",
26
+ "zod": "^4.1.13",
26
27
  "ws": "^8.18.3"
27
28
  },
28
29
  "files": [
@@ -1,87 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var browser_input_exports = {};
20
- __export(browser_input_exports, {
21
- MAX_VIEWPORT_DIMENSION: () => MAX_VIEWPORT_DIMENSION,
22
- normalizeBrowserInput: () => normalizeBrowserInput,
23
- parseViewportInput: () => parseViewportInput
24
- });
25
- module.exports = __toCommonJS(browser_input_exports);
26
- const browserInputFields = {
27
- list_tabs: { required: [], optional: [] },
28
- list_downloads: { required: [], optional: [] },
29
- get_download: { required: ["downloadId"], optional: ["offset", "maxBytes"] },
30
- open_tab: { required: [], optional: ["url", "disposition"] },
31
- close_tab: { required: ["tabId"], optional: [] },
32
- navigate: { required: ["tabId", "url"], optional: [] },
33
- set_viewport: { required: ["tabId"], optional: ["width", "height", "reset"] },
34
- read_page: { required: ["tabId"], optional: ["depth", "maxChars"] },
35
- screenshot: { required: ["tabId"], optional: ["fullPage"] },
36
- move_mouse: { required: ["tabId", "x", "y"], optional: [] },
37
- mouse_click: { required: ["tabId"], optional: ["ref", "x", "y", "button", "clickCount"] },
38
- scroll: { required: ["tabId"], optional: ["ref", "direction", "amount", "x", "y"] },
39
- wait_for: { required: ["tabId"], optional: ["selector", "text", "url", "loadState", "state", "timeoutMs"] },
40
- form_input: { required: ["tabId", "ref"], optional: ["value", "values", "checked"] },
41
- keyboard: { required: ["tabId", "keys"], optional: ["modifiers"] },
42
- keyboard_type: { required: ["tabId", "text"], optional: ["mode", "delayMs"] },
43
- run_js: { required: ["tabId", "code"], optional: [] },
44
- upload_files: { required: ["tabId", "files"], optional: ["ref", "selector"] },
45
- upload_begin: { required: ["tabId", "uploadId", "files"], optional: ["ref", "selector"] },
46
- upload_chunk: { required: ["tabId", "uploadId", "index", "offset", "base64"], optional: [] },
47
- upload_attach: { required: ["tabId", "uploadId", "hashes"], optional: [] },
48
- upload_abort: { required: ["tabId", "uploadId"], optional: [] },
49
- port_forward: { required: ["workerPort"], optional: ["browserPort"] },
50
- list_port_forwards: { required: [], optional: [] },
51
- stop_port_forward: { required: ["forwardId"], optional: [] }
52
- };
53
- const MAX_VIEWPORT_DIMENSION = 4096;
54
- function parseViewportInput(input) {
55
- if (input.reset !== void 0 && typeof input.reset !== "boolean") throw new Error("set_viewport reset must be a boolean.");
56
- if (input.reset === true) {
57
- if (input.width !== void 0 || input.height !== void 0)
58
- throw new Error("set_viewport accepts width/height or reset: true, not both.");
59
- return null;
60
- }
61
- const { width, height } = input;
62
- for (const [name, value] of Object.entries({ width, height })) {
63
- if (typeof value !== "number" || !Number.isInteger(value) || value < 1 || value > MAX_VIEWPORT_DIMENSION) {
64
- throw new Error(
65
- `set_viewport requires ${name} to be an integer from 1 to ${MAX_VIEWPORT_DIMENSION} CSS pixels, or reset: true without dimensions.`
66
- );
67
- }
68
- }
69
- return { width, height };
70
- }
71
- function normalizeBrowserInput(action, input) {
72
- const fields = browserInputFields[action];
73
- for (const key of fields.required) {
74
- if (input[key] === null || input[key] === void 0) throw new Error(`${action} requires ${key}.`);
75
- }
76
- const normalized = { ...input };
77
- for (const key of fields.optional) {
78
- if (normalized[key] === null) delete normalized[key];
79
- }
80
- return normalized;
81
- }
82
- // Annotate the CommonJS export names for ESM import in node:
83
- 0 && (module.exports = {
84
- MAX_VIEWPORT_DIMENSION,
85
- normalizeBrowserInput,
86
- parseViewportInput
87
- });