UNPKG

4.62 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 return new (P || (P = Promise))(function (resolve, reject) {
4 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7 step((generator = generator.apply(thisArg, _arguments || [])).next());
8 });
9};
10var __importDefault = (this && this.__importDefault) || function (mod) {
11 return (mod && mod.__esModule) ? mod : { "default": mod };
12};
13Object.defineProperty(exports, "__esModule", { value: true });
14const function_handle_registry_1 = __importDefault(require("./function-handle-registry"));
15const command_coordinator_1 = __importDefault(require("./command-coordinator"));
16class Stagehand {
17 constructor(implementation) {
18 this.rehydrateRemoteFunction = (handleID) => {
19 return (...params) => {
20 if (!this.commandCoordinator) {
21 throw new Error('Cannot call function through a disconnected stagehand');
22 }
23 return this.commandCoordinator.sendCommand('call', handleID, params);
24 };
25 };
26 this.executor = {
27 call: (name, args) => {
28 let thisValue;
29 let fun;
30 if (typeof name === 'string') {
31 fun = this.implementation && this.implementation[name];
32 thisValue = this.implementation;
33 }
34 else {
35 fun = this.handleRegistry.lookupFunction(name);
36 thisValue = null;
37 }
38 if (typeof fun !== 'function') {
39 throw new Error('Unable to call a nonexistent or non-function field ');
40 }
41 return fun.apply(thisValue, args);
42 },
43 handshake: () => {
44 if (!this.implementation) {
45 return { name: 'void', methods: [] };
46 }
47 let name = this.implementation.constructor.name;
48 let methods = [];
49 let object = this.implementation;
50 while (object && object !== Object.prototype) {
51 for (let key of Object.getOwnPropertyNames(object)) {
52 if (typeof this.implementation[key] === 'function' && key !== 'constructor') {
53 methods.push(key);
54 }
55 }
56 object = Object.getPrototypeOf(object);
57 }
58 return { name, methods };
59 },
60 disconnect: () => {
61 setTimeout(() => this.shutdown());
62 }
63 };
64 this.implementation = implementation;
65 this.handleRegistry = new function_handle_registry_1.default(this.rehydrateRemoteFunction);
66 }
67 isConnected() {
68 return !!this.commandCoordinator;
69 }
70 listen(endpoint) {
71 return __awaiter(this, void 0, void 0, function* () {
72 yield this.startup(endpoint);
73 });
74 }
75 connect(endpoint) {
76 return __awaiter(this, void 0, void 0, function* () {
77 yield this.startup(endpoint);
78 return this.commandCoordinator.sendCommand('handshake');
79 });
80 }
81 call(method, args) {
82 return __awaiter(this, void 0, void 0, function* () {
83 if (!this.commandCoordinator) {
84 throw new Error('Stagehand is disconnected');
85 }
86 return this.commandCoordinator.sendCommand('call', method, args);
87 });
88 }
89 disconnect() {
90 return __awaiter(this, void 0, void 0, function* () {
91 if (this.commandCoordinator) {
92 yield this.commandCoordinator.sendCommand('disconnect');
93 }
94 this.shutdown();
95 });
96 }
97 startup(endpoint) {
98 return __awaiter(this, void 0, void 0, function* () {
99 yield this.disconnect();
100 this.endpoint = endpoint;
101 this.commandCoordinator = new command_coordinator_1.default(endpoint, this.handleRegistry, this.executor);
102 });
103 }
104 shutdown() {
105 this.handleRegistry.reset();
106 this.commandCoordinator = undefined;
107 if (this.endpoint) {
108 this.endpoint.disconnect();
109 }
110 }
111}
112exports.default = Stagehand;