@runhuman/sensor 0.1.2 → 0.2.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/dist/{index.d.cts → index.d.mts} +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +96 -20
- package/dist/index.js.map +1 -1
- package/dist/{index.cjs → index.mjs} +77 -41
- package/dist/index.mjs.map +1 -0
- package/dist/overlay/index.d.mts +30 -0
- package/dist/overlay/index.d.ts +30 -0
- package/dist/overlay/index.js +1426 -0
- package/dist/overlay/index.js.map +1 -0
- package/dist/overlay/index.mjs +1405 -0
- package/dist/overlay/index.mjs.map +1 -0
- package/dist/session-manager-B6tiwEQm.d.mts +99 -0
- package/dist/session-manager-B6tiwEQm.d.ts +99 -0
- package/package.json +24 -5
- package/dist/index.cjs.map +0 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { TelemetryPlatform } from '@runhuman/shared';
|
|
2
2
|
export { TelemetryPlatform } from '@runhuman/shared';
|
|
3
|
+
import { S as SessionManager, A as ApiClient } from './session-manager-B6tiwEQm.mjs';
|
|
4
|
+
export { a as SessionState } from './session-manager-B6tiwEQm.mjs';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Runhuman Sensor — Public API
|
|
@@ -35,6 +37,7 @@ interface RunhumanConfig {
|
|
|
35
37
|
}
|
|
36
38
|
declare class Runhuman {
|
|
37
39
|
private static instance;
|
|
40
|
+
private readonly apiClient;
|
|
38
41
|
private readonly sessionManager;
|
|
39
42
|
private readonly deepLinkHandler;
|
|
40
43
|
private readonly debug;
|
|
@@ -68,7 +71,11 @@ declare class Runhuman {
|
|
|
68
71
|
* After calling destroy(), you can call init() again.
|
|
69
72
|
*/
|
|
70
73
|
destroy(): Promise<void>;
|
|
74
|
+
/** Access the session manager (used by <RunhumanOverlay /> for reactive state) */
|
|
75
|
+
getSessionManager(): SessionManager;
|
|
76
|
+
/** Access the API client (used by <RunhumanOverlay /> for short code resolution) */
|
|
77
|
+
getApiClient(): ApiClient;
|
|
71
78
|
private log;
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
export { Runhuman, type RunhumanConfig };
|
|
81
|
+
export { ApiClient, Runhuman, type RunhumanConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { TelemetryPlatform } from '@runhuman/shared';
|
|
2
2
|
export { TelemetryPlatform } from '@runhuman/shared';
|
|
3
|
+
import { S as SessionManager, A as ApiClient } from './session-manager-B6tiwEQm.js';
|
|
4
|
+
export { a as SessionState } from './session-manager-B6tiwEQm.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Runhuman Sensor — Public API
|
|
@@ -35,6 +37,7 @@ interface RunhumanConfig {
|
|
|
35
37
|
}
|
|
36
38
|
declare class Runhuman {
|
|
37
39
|
private static instance;
|
|
40
|
+
private readonly apiClient;
|
|
38
41
|
private readonly sessionManager;
|
|
39
42
|
private readonly deepLinkHandler;
|
|
40
43
|
private readonly debug;
|
|
@@ -68,7 +71,11 @@ declare class Runhuman {
|
|
|
68
71
|
* After calling destroy(), you can call init() again.
|
|
69
72
|
*/
|
|
70
73
|
destroy(): Promise<void>;
|
|
74
|
+
/** Access the session manager (used by <RunhumanOverlay /> for reactive state) */
|
|
75
|
+
getSessionManager(): SessionManager;
|
|
76
|
+
/** Access the API client (used by <RunhumanOverlay /> for short code resolution) */
|
|
77
|
+
getApiClient(): ApiClient;
|
|
71
78
|
private log;
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
export { Runhuman, type RunhumanConfig };
|
|
81
|
+
export { ApiClient, Runhuman, type RunhumanConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
Runhuman: () => Runhuman
|
|
6
24
|
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
7
26
|
|
|
8
27
|
// ../shared/dist/routes/route-builder.js
|
|
9
28
|
var API_PREFIX = "/api";
|
|
@@ -74,6 +93,8 @@ var webRoutes = {
|
|
|
74
93
|
organizationGitHub: defineRoute("/dashboard/organizations/:organizationId/github"),
|
|
75
94
|
/** Organization SSO/SAML configuration page */
|
|
76
95
|
organizationSso: defineRoute("/dashboard/organizations/:organizationId/sso"),
|
|
96
|
+
/** Organization schedules overview */
|
|
97
|
+
organizationSchedules: defineRoute("/dashboard/organizations/:organizationId/schedules"),
|
|
77
98
|
/** Import from GitHub page */
|
|
78
99
|
organizationImportGitHub: defineRoute("/dashboard/organizations/:organizationId/import"),
|
|
79
100
|
// ============================================
|
|
@@ -119,6 +140,8 @@ var webRoutes = {
|
|
|
119
140
|
issueSession: defineRoute("/dashboard/:projectId/issue-sessions/:sessionId"),
|
|
120
141
|
/** Project settings page */
|
|
121
142
|
projectSettings: defineRoute("/dashboard/:projectId/settings"),
|
|
143
|
+
/** Schedules page */
|
|
144
|
+
schedules: defineRoute("/dashboard/:projectId/schedules"),
|
|
122
145
|
/** Flow charts page */
|
|
123
146
|
flowCharts: defineRoute("/dashboard/:projectId/flowcharts"),
|
|
124
147
|
/** Single flow chart detail (embedded in dashboard - deprecated, use flowChartView) */
|
|
@@ -162,6 +185,8 @@ var apiRoutes = {
|
|
|
162
185
|
job: defineRoute("/jobs/:jobId"),
|
|
163
186
|
/** Get job status (for polling) */
|
|
164
187
|
jobStatus: defineRoute("/jobs/:jobId/status"),
|
|
188
|
+
/** Get individual job artifact by type */
|
|
189
|
+
jobArtifact: defineRoute("/jobs/:jobId/artifacts/:artifactType"),
|
|
165
190
|
/** Update job feedback and rating */
|
|
166
191
|
jobFeedback: defineRoute("/jobs/:jobId/feedback"),
|
|
167
192
|
/** Enable/disable public sharing for a job (POST = enable, DELETE = disable) */
|
|
@@ -257,6 +282,12 @@ var apiRoutes = {
|
|
|
257
282
|
projectFlowChartChat: defineRoute("/projects/:projectId/flowcharts/:flowchartId/chat"),
|
|
258
283
|
/** Enable/disable public sharing for a flow chart */
|
|
259
284
|
projectFlowChartShare: defineRoute("/projects/:projectId/flowcharts/:flowchartId/share"),
|
|
285
|
+
/** List schedules for a project (GET) or create schedule (POST) */
|
|
286
|
+
projectSchedules: defineRoute("/projects/:projectId/schedules"),
|
|
287
|
+
/** Get/update/delete specific schedule */
|
|
288
|
+
projectSchedule: defineRoute("/projects/:projectId/schedules/:scheduleId"),
|
|
289
|
+
/** List execution history for a schedule */
|
|
290
|
+
projectScheduleExecutions: defineRoute("/projects/:projectId/schedules/:scheduleId/executions"),
|
|
260
291
|
/** Bulk create projects from GitHub repos */
|
|
261
292
|
bulkCreateProjects: defineRoute("/projects/bulk"),
|
|
262
293
|
// ============================================
|
|
@@ -438,6 +469,8 @@ var apiRoutes = {
|
|
|
438
469
|
organizationGitHubRepoCheckAccess: defineRoute("/organizations/:organizationId/github/repos/check-access"),
|
|
439
470
|
/** Find deployed URL for a repo via org's GitHub installations */
|
|
440
471
|
organizationGitHubRepoFindUrl: defineRoute("/organizations/:organizationId/github/repos/find-url"),
|
|
472
|
+
/** Get all schedules across projects in the organization */
|
|
473
|
+
organizationSchedules: defineRoute("/organizations/:organizationId/schedules"),
|
|
441
474
|
/** Get organization billing balance (Polar) */
|
|
442
475
|
organizationBilling: defineRoute("/organizations/:organizationId/billing"),
|
|
443
476
|
// ============================================
|
|
@@ -498,7 +531,9 @@ var apiRoutes = {
|
|
|
498
531
|
/** Submit telemetry event batch (POST) — SDK periodically flushes captured events */
|
|
499
532
|
telemetryBatch: defineRoute("/telemetry/sessions/:sessionId/events"),
|
|
500
533
|
/** Check session status for a job (GET) — SDK polls to know when to activate */
|
|
501
|
-
telemetrySessionStatus: defineRoute("/telemetry/jobs/:jobId/status")
|
|
534
|
+
telemetrySessionStatus: defineRoute("/telemetry/jobs/:jobId/status"),
|
|
535
|
+
/** Resolve a sensor short code to a jobId (GET) — SDK calls this when tester enters a code */
|
|
536
|
+
telemetryShortCodeResolve: defineRoute("/telemetry/short-codes/:code")
|
|
502
537
|
};
|
|
503
538
|
|
|
504
539
|
// src/api-client.ts
|
|
@@ -529,6 +564,17 @@ var ApiClient = class {
|
|
|
529
564
|
async getSessionStatus(jobId) {
|
|
530
565
|
return this.get(apiRoutes.telemetrySessionStatus.build({ jobId }));
|
|
531
566
|
}
|
|
567
|
+
async resolveShortCode(code) {
|
|
568
|
+
const normalized = code.replace(/^RH-/i, "").toUpperCase();
|
|
569
|
+
try {
|
|
570
|
+
return await this.get(
|
|
571
|
+
apiRoutes.telemetryShortCodeResolve.build({ code: normalized })
|
|
572
|
+
);
|
|
573
|
+
} catch (error) {
|
|
574
|
+
if (error instanceof Error && error.message.includes("404")) return null;
|
|
575
|
+
throw error;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
532
578
|
url(routePath) {
|
|
533
579
|
return `${this.baseUrl}${API_PREFIX}${routePath}`;
|
|
534
580
|
}
|
|
@@ -798,6 +844,7 @@ var SessionManager = class {
|
|
|
798
844
|
this.activeJobId = null;
|
|
799
845
|
this.pollTimer = null;
|
|
800
846
|
this.flushTimer = null;
|
|
847
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
801
848
|
this.config = config;
|
|
802
849
|
this.buffer = new EventBuffer(config.maxBufferSize);
|
|
803
850
|
this.interceptors = new InterceptorManager();
|
|
@@ -805,9 +852,30 @@ var SessionManager = class {
|
|
|
805
852
|
getState() {
|
|
806
853
|
return this.state;
|
|
807
854
|
}
|
|
855
|
+
/** Alias for getState() — named for React's useSyncExternalStore convention */
|
|
856
|
+
getSnapshot() {
|
|
857
|
+
return this.state;
|
|
858
|
+
}
|
|
808
859
|
getSessionId() {
|
|
809
860
|
return this.sessionId;
|
|
810
861
|
}
|
|
862
|
+
getActiveJobId() {
|
|
863
|
+
return this.activeJobId;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Subscribe to state changes. Returns an unsubscribe function.
|
|
867
|
+
* Compatible with React's useSyncExternalStore.
|
|
868
|
+
*/
|
|
869
|
+
subscribe(listener) {
|
|
870
|
+
this.listeners.add(listener);
|
|
871
|
+
return () => this.listeners.delete(listener);
|
|
872
|
+
}
|
|
873
|
+
setState(newState) {
|
|
874
|
+
this.state = newState;
|
|
875
|
+
for (const listener of this.listeners) {
|
|
876
|
+
listener();
|
|
877
|
+
}
|
|
878
|
+
}
|
|
811
879
|
/**
|
|
812
880
|
* Start polling for job activation.
|
|
813
881
|
* The sensor calls this on init — polling continues until a job is detected
|
|
@@ -816,7 +884,7 @@ var SessionManager = class {
|
|
|
816
884
|
startPolling(jobId) {
|
|
817
885
|
if (this.state !== "idle") return;
|
|
818
886
|
this.activeJobId = jobId;
|
|
819
|
-
this.
|
|
887
|
+
this.setState("polling");
|
|
820
888
|
this.log("Polling started", { jobId });
|
|
821
889
|
this.pollTimer = setInterval(() => this.pollOnce(), this.config.pollIntervalMs);
|
|
822
890
|
this.pollOnce();
|
|
@@ -827,7 +895,7 @@ var SessionManager = class {
|
|
|
827
895
|
this.pollTimer = null;
|
|
828
896
|
}
|
|
829
897
|
if (this.state === "polling") {
|
|
830
|
-
this.
|
|
898
|
+
this.setState("idle");
|
|
831
899
|
this.log("Polling stopped");
|
|
832
900
|
}
|
|
833
901
|
}
|
|
@@ -864,10 +932,9 @@ var SessionManager = class {
|
|
|
864
932
|
if (this.state !== "polling" || !this.activeJobId) return;
|
|
865
933
|
try {
|
|
866
934
|
const status = await this.config.apiClient.getSessionStatus(this.activeJobId);
|
|
867
|
-
if (status.jobActive && status.
|
|
868
|
-
this.log("Job
|
|
869
|
-
jobId: this.activeJobId
|
|
870
|
-
activeSessionId: status.activeSessionId
|
|
935
|
+
if (status.jobActive && !status.activeSessionId) {
|
|
936
|
+
this.log("Job is active, creating session", {
|
|
937
|
+
jobId: this.activeJobId
|
|
871
938
|
});
|
|
872
939
|
this.stopPolling();
|
|
873
940
|
await this.startSession();
|
|
@@ -877,7 +944,7 @@ var SessionManager = class {
|
|
|
877
944
|
}
|
|
878
945
|
}
|
|
879
946
|
async startSession() {
|
|
880
|
-
this.
|
|
947
|
+
this.setState("active");
|
|
881
948
|
const now = /* @__PURE__ */ new Date();
|
|
882
949
|
const response = await this.config.apiClient.createSession({
|
|
883
950
|
jobId: this.activeJobId,
|
|
@@ -896,7 +963,7 @@ var SessionManager = class {
|
|
|
896
963
|
this.flushTimer = setInterval(() => this.flush(), this.config.flushIntervalMs);
|
|
897
964
|
}
|
|
898
965
|
async endSession() {
|
|
899
|
-
this.
|
|
966
|
+
this.setState("ending");
|
|
900
967
|
if (this.flushTimer) {
|
|
901
968
|
clearInterval(this.flushTimer);
|
|
902
969
|
this.flushTimer = null;
|
|
@@ -918,7 +985,7 @@ var SessionManager = class {
|
|
|
918
985
|
this.sessionId = null;
|
|
919
986
|
this.activeJobId = null;
|
|
920
987
|
this.buffer.clear();
|
|
921
|
-
this.
|
|
988
|
+
this.setState("idle");
|
|
922
989
|
}
|
|
923
990
|
async flush() {
|
|
924
991
|
if (!this.sessionId) return;
|
|
@@ -990,7 +1057,7 @@ var DeepLinkHandler = class {
|
|
|
990
1057
|
}
|
|
991
1058
|
getLinking() {
|
|
992
1059
|
try {
|
|
993
|
-
const { Linking } =
|
|
1060
|
+
const { Linking } = require("react-native");
|
|
994
1061
|
return Linking;
|
|
995
1062
|
} catch {
|
|
996
1063
|
return null;
|
|
@@ -1009,12 +1076,12 @@ var SDK_VERSION = "0.1.0";
|
|
|
1009
1076
|
var _Runhuman = class _Runhuman {
|
|
1010
1077
|
constructor(config) {
|
|
1011
1078
|
this.debug = config.debug === true;
|
|
1012
|
-
|
|
1079
|
+
this.apiClient = new ApiClient(
|
|
1013
1080
|
config.baseUrl ?? PRODUCTION_BASE_URL,
|
|
1014
1081
|
config.apiKey
|
|
1015
1082
|
);
|
|
1016
1083
|
this.sessionManager = new SessionManager({
|
|
1017
|
-
apiClient,
|
|
1084
|
+
apiClient: this.apiClient,
|
|
1018
1085
|
platform: config.platform ?? "react-native",
|
|
1019
1086
|
sdkVersion: SDK_VERSION,
|
|
1020
1087
|
flushIntervalMs: config.flushIntervalMs ?? 5e3,
|
|
@@ -1085,6 +1152,14 @@ var _Runhuman = class _Runhuman {
|
|
|
1085
1152
|
_Runhuman.instance = null;
|
|
1086
1153
|
this.log("Destroyed");
|
|
1087
1154
|
}
|
|
1155
|
+
/** Access the session manager (used by <RunhumanOverlay /> for reactive state) */
|
|
1156
|
+
getSessionManager() {
|
|
1157
|
+
return this.sessionManager;
|
|
1158
|
+
}
|
|
1159
|
+
/** Access the API client (used by <RunhumanOverlay /> for short code resolution) */
|
|
1160
|
+
getApiClient() {
|
|
1161
|
+
return this.apiClient;
|
|
1162
|
+
}
|
|
1088
1163
|
log(message) {
|
|
1089
1164
|
if (this.debug) {
|
|
1090
1165
|
console.debug(`[Runhuman] ${message}`);
|
|
@@ -1093,7 +1168,8 @@ var _Runhuman = class _Runhuman {
|
|
|
1093
1168
|
};
|
|
1094
1169
|
_Runhuman.instance = null;
|
|
1095
1170
|
var Runhuman = _Runhuman;
|
|
1096
|
-
export
|
|
1171
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1172
|
+
0 && (module.exports = {
|
|
1097
1173
|
Runhuman
|
|
1098
|
-
};
|
|
1174
|
+
});
|
|
1099
1175
|
//# sourceMappingURL=index.js.map
|