@runhuman/sensor 0.1.3 → 0.2.1
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.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +68 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +68 -12
- package/dist/index.mjs.map +1 -1
- package/dist/overlay/index.d.mts +34 -0
- package/dist/overlay/index.d.ts +34 -0
- package/dist/overlay/index.js +1445 -0
- package/dist/overlay/index.js.map +1 -0
- package/dist/overlay/index.mjs +1424 -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 +20 -8
package/dist/index.d.mts
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.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
|
@@ -93,6 +93,8 @@ var webRoutes = {
|
|
|
93
93
|
organizationGitHub: defineRoute("/dashboard/organizations/:organizationId/github"),
|
|
94
94
|
/** Organization SSO/SAML configuration page */
|
|
95
95
|
organizationSso: defineRoute("/dashboard/organizations/:organizationId/sso"),
|
|
96
|
+
/** Organization schedules overview */
|
|
97
|
+
organizationSchedules: defineRoute("/dashboard/organizations/:organizationId/schedules"),
|
|
96
98
|
/** Import from GitHub page */
|
|
97
99
|
organizationImportGitHub: defineRoute("/dashboard/organizations/:organizationId/import"),
|
|
98
100
|
// ============================================
|
|
@@ -138,6 +140,8 @@ var webRoutes = {
|
|
|
138
140
|
issueSession: defineRoute("/dashboard/:projectId/issue-sessions/:sessionId"),
|
|
139
141
|
/** Project settings page */
|
|
140
142
|
projectSettings: defineRoute("/dashboard/:projectId/settings"),
|
|
143
|
+
/** Schedules page */
|
|
144
|
+
schedules: defineRoute("/dashboard/:projectId/schedules"),
|
|
141
145
|
/** Flow charts page */
|
|
142
146
|
flowCharts: defineRoute("/dashboard/:projectId/flowcharts"),
|
|
143
147
|
/** Single flow chart detail (embedded in dashboard - deprecated, use flowChartView) */
|
|
@@ -181,6 +185,8 @@ var apiRoutes = {
|
|
|
181
185
|
job: defineRoute("/jobs/:jobId"),
|
|
182
186
|
/** Get job status (for polling) */
|
|
183
187
|
jobStatus: defineRoute("/jobs/:jobId/status"),
|
|
188
|
+
/** Get individual job artifact by type */
|
|
189
|
+
jobArtifact: defineRoute("/jobs/:jobId/artifacts/:artifactType"),
|
|
184
190
|
/** Update job feedback and rating */
|
|
185
191
|
jobFeedback: defineRoute("/jobs/:jobId/feedback"),
|
|
186
192
|
/** Enable/disable public sharing for a job (POST = enable, DELETE = disable) */
|
|
@@ -276,6 +282,12 @@ var apiRoutes = {
|
|
|
276
282
|
projectFlowChartChat: defineRoute("/projects/:projectId/flowcharts/:flowchartId/chat"),
|
|
277
283
|
/** Enable/disable public sharing for a flow chart */
|
|
278
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"),
|
|
279
291
|
/** Bulk create projects from GitHub repos */
|
|
280
292
|
bulkCreateProjects: defineRoute("/projects/bulk"),
|
|
281
293
|
// ============================================
|
|
@@ -457,6 +469,8 @@ var apiRoutes = {
|
|
|
457
469
|
organizationGitHubRepoCheckAccess: defineRoute("/organizations/:organizationId/github/repos/check-access"),
|
|
458
470
|
/** Find deployed URL for a repo via org's GitHub installations */
|
|
459
471
|
organizationGitHubRepoFindUrl: defineRoute("/organizations/:organizationId/github/repos/find-url"),
|
|
472
|
+
/** Get all schedules across projects in the organization */
|
|
473
|
+
organizationSchedules: defineRoute("/organizations/:organizationId/schedules"),
|
|
460
474
|
/** Get organization billing balance (Polar) */
|
|
461
475
|
organizationBilling: defineRoute("/organizations/:organizationId/billing"),
|
|
462
476
|
// ============================================
|
|
@@ -517,7 +531,9 @@ var apiRoutes = {
|
|
|
517
531
|
/** Submit telemetry event batch (POST) — SDK periodically flushes captured events */
|
|
518
532
|
telemetryBatch: defineRoute("/telemetry/sessions/:sessionId/events"),
|
|
519
533
|
/** Check session status for a job (GET) — SDK polls to know when to activate */
|
|
520
|
-
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")
|
|
521
537
|
};
|
|
522
538
|
|
|
523
539
|
// src/api-client.ts
|
|
@@ -548,6 +564,17 @@ var ApiClient = class {
|
|
|
548
564
|
async getSessionStatus(jobId) {
|
|
549
565
|
return this.get(apiRoutes.telemetrySessionStatus.build({ jobId }));
|
|
550
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
|
+
}
|
|
551
578
|
url(routePath) {
|
|
552
579
|
return `${this.baseUrl}${API_PREFIX}${routePath}`;
|
|
553
580
|
}
|
|
@@ -817,6 +844,7 @@ var SessionManager = class {
|
|
|
817
844
|
this.activeJobId = null;
|
|
818
845
|
this.pollTimer = null;
|
|
819
846
|
this.flushTimer = null;
|
|
847
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
820
848
|
this.config = config;
|
|
821
849
|
this.buffer = new EventBuffer(config.maxBufferSize);
|
|
822
850
|
this.interceptors = new InterceptorManager();
|
|
@@ -824,9 +852,30 @@ var SessionManager = class {
|
|
|
824
852
|
getState() {
|
|
825
853
|
return this.state;
|
|
826
854
|
}
|
|
855
|
+
/** Alias for getState() — named for React's useSyncExternalStore convention */
|
|
856
|
+
getSnapshot() {
|
|
857
|
+
return this.state;
|
|
858
|
+
}
|
|
827
859
|
getSessionId() {
|
|
828
860
|
return this.sessionId;
|
|
829
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
|
+
}
|
|
830
879
|
/**
|
|
831
880
|
* Start polling for job activation.
|
|
832
881
|
* The sensor calls this on init — polling continues until a job is detected
|
|
@@ -835,7 +884,7 @@ var SessionManager = class {
|
|
|
835
884
|
startPolling(jobId) {
|
|
836
885
|
if (this.state !== "idle") return;
|
|
837
886
|
this.activeJobId = jobId;
|
|
838
|
-
this.
|
|
887
|
+
this.setState("polling");
|
|
839
888
|
this.log("Polling started", { jobId });
|
|
840
889
|
this.pollTimer = setInterval(() => this.pollOnce(), this.config.pollIntervalMs);
|
|
841
890
|
this.pollOnce();
|
|
@@ -846,7 +895,7 @@ var SessionManager = class {
|
|
|
846
895
|
this.pollTimer = null;
|
|
847
896
|
}
|
|
848
897
|
if (this.state === "polling") {
|
|
849
|
-
this.
|
|
898
|
+
this.setState("idle");
|
|
850
899
|
this.log("Polling stopped");
|
|
851
900
|
}
|
|
852
901
|
}
|
|
@@ -883,10 +932,9 @@ var SessionManager = class {
|
|
|
883
932
|
if (this.state !== "polling" || !this.activeJobId) return;
|
|
884
933
|
try {
|
|
885
934
|
const status = await this.config.apiClient.getSessionStatus(this.activeJobId);
|
|
886
|
-
if (status.jobActive && status.
|
|
887
|
-
this.log("Job
|
|
888
|
-
jobId: this.activeJobId
|
|
889
|
-
activeSessionId: status.activeSessionId
|
|
935
|
+
if (status.jobActive && !status.activeSessionId) {
|
|
936
|
+
this.log("Job is active, creating session", {
|
|
937
|
+
jobId: this.activeJobId
|
|
890
938
|
});
|
|
891
939
|
this.stopPolling();
|
|
892
940
|
await this.startSession();
|
|
@@ -896,7 +944,7 @@ var SessionManager = class {
|
|
|
896
944
|
}
|
|
897
945
|
}
|
|
898
946
|
async startSession() {
|
|
899
|
-
this.
|
|
947
|
+
this.setState("active");
|
|
900
948
|
const now = /* @__PURE__ */ new Date();
|
|
901
949
|
const response = await this.config.apiClient.createSession({
|
|
902
950
|
jobId: this.activeJobId,
|
|
@@ -915,7 +963,7 @@ var SessionManager = class {
|
|
|
915
963
|
this.flushTimer = setInterval(() => this.flush(), this.config.flushIntervalMs);
|
|
916
964
|
}
|
|
917
965
|
async endSession() {
|
|
918
|
-
this.
|
|
966
|
+
this.setState("ending");
|
|
919
967
|
if (this.flushTimer) {
|
|
920
968
|
clearInterval(this.flushTimer);
|
|
921
969
|
this.flushTimer = null;
|
|
@@ -937,7 +985,7 @@ var SessionManager = class {
|
|
|
937
985
|
this.sessionId = null;
|
|
938
986
|
this.activeJobId = null;
|
|
939
987
|
this.buffer.clear();
|
|
940
|
-
this.
|
|
988
|
+
this.setState("idle");
|
|
941
989
|
}
|
|
942
990
|
async flush() {
|
|
943
991
|
if (!this.sessionId) return;
|
|
@@ -1028,12 +1076,12 @@ var SDK_VERSION = "0.1.0";
|
|
|
1028
1076
|
var _Runhuman = class _Runhuman {
|
|
1029
1077
|
constructor(config) {
|
|
1030
1078
|
this.debug = config.debug === true;
|
|
1031
|
-
|
|
1079
|
+
this.apiClient = new ApiClient(
|
|
1032
1080
|
config.baseUrl ?? PRODUCTION_BASE_URL,
|
|
1033
1081
|
config.apiKey
|
|
1034
1082
|
);
|
|
1035
1083
|
this.sessionManager = new SessionManager({
|
|
1036
|
-
apiClient,
|
|
1084
|
+
apiClient: this.apiClient,
|
|
1037
1085
|
platform: config.platform ?? "react-native",
|
|
1038
1086
|
sdkVersion: SDK_VERSION,
|
|
1039
1087
|
flushIntervalMs: config.flushIntervalMs ?? 5e3,
|
|
@@ -1104,6 +1152,14 @@ var _Runhuman = class _Runhuman {
|
|
|
1104
1152
|
_Runhuman.instance = null;
|
|
1105
1153
|
this.log("Destroyed");
|
|
1106
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
|
+
}
|
|
1107
1163
|
log(message) {
|
|
1108
1164
|
if (this.debug) {
|
|
1109
1165
|
console.debug(`[Runhuman] ${message}`);
|