@roj-ai/client 0.1.3 → 0.1.5

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 (56) hide show
  1. package/dist/api/client.d.ts +1 -0
  2. package/dist/api/client.d.ts.map +1 -0
  3. package/dist/api/client.js +57 -0
  4. package/dist/api/client.js.map +1 -0
  5. package/dist/api/unwrap.d.ts +1 -0
  6. package/dist/api/unwrap.d.ts.map +1 -0
  7. package/dist/api/unwrap.js +7 -0
  8. package/dist/api/unwrap.js.map +1 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +9 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/platform/errors.d.ts +1 -0
  14. package/dist/platform/errors.d.ts.map +1 -0
  15. package/dist/platform/errors.js +20 -0
  16. package/dist/platform/errors.js.map +1 -0
  17. package/dist/platform/index.d.ts +2 -1
  18. package/dist/platform/index.d.ts.map +1 -0
  19. package/dist/platform/index.js +20 -0
  20. package/dist/platform/index.js.map +1 -0
  21. package/dist/platform/instance-methods.d.ts +1 -0
  22. package/dist/platform/instance-methods.d.ts.map +1 -0
  23. package/dist/platform/instance-methods.js +34 -0
  24. package/dist/platform/instance-methods.js.map +1 -0
  25. package/dist/platform/methods.d.ts +35 -0
  26. package/dist/platform/methods.d.ts.map +1 -0
  27. package/dist/platform/methods.js +38 -0
  28. package/dist/platform/methods.js.map +1 -0
  29. package/dist/platform/rest-client.d.ts +26 -1
  30. package/dist/platform/rest-client.d.ts.map +1 -0
  31. package/dist/platform/rest-client.js +116 -0
  32. package/dist/platform/rest-client.js.map +1 -0
  33. package/dist/platform/rpc-client.d.ts +1 -0
  34. package/dist/platform/rpc-client.d.ts.map +1 -0
  35. package/dist/platform/rpc-client.js +30 -0
  36. package/dist/platform/rpc-client.js.map +1 -0
  37. package/dist/platform/rpc-definition.d.ts +1 -0
  38. package/dist/platform/rpc-definition.d.ts.map +1 -0
  39. package/dist/platform/rpc-definition.js +19 -0
  40. package/dist/platform/rpc-definition.js.map +1 -0
  41. package/dist/platform/rpc-server.d.ts +1 -0
  42. package/dist/platform/rpc-server.d.ts.map +1 -0
  43. package/dist/platform/rpc-server.js +24 -0
  44. package/dist/platform/rpc-server.js.map +1 -0
  45. package/dist/platform/sandbox-state.d.ts +1 -0
  46. package/dist/platform/sandbox-state.d.ts.map +1 -0
  47. package/dist/platform/sandbox-state.js +2 -0
  48. package/dist/platform/sandbox-state.js.map +1 -0
  49. package/dist/platform/urls.d.ts +1 -0
  50. package/dist/platform/urls.d.ts.map +1 -0
  51. package/dist/platform/urls.js +42 -0
  52. package/dist/platform/urls.js.map +1 -0
  53. package/package.json +9 -9
  54. package/src/platform/index.ts +1 -1
  55. package/src/platform/methods.ts +43 -0
  56. package/src/platform/rest-client.ts +91 -0
@@ -16,3 +16,4 @@ export declare function configureProjectId(projectId: string | null): void;
16
16
  export declare function createApiClient(baseUrl?: string): ApiClient;
17
17
  export declare const api: ApiClient;
18
18
  export declare function useApiError(error: unknown): string | null;
19
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAElG,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;AAC9B,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B,MAAM,WAAW,SAAS;IACzB,IAAI,CAAC,CAAC,SAAS,aAAa,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAA;IACzG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC/H;AAkCD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAMrD;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEjE;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,MAAW,GAAG,SAAS,CAG/D;AAED,eAAO,MAAM,GAAG,EAAE,SAAmD,CAAA;AAErE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQzD"}
@@ -0,0 +1,57 @@
1
+ import { RpcClient, RpcError } from '@roj-ai/shared/rpc';
2
+ export { RpcClient, RpcError };
3
+ function createApiClientFromRpc(getClient) {
4
+ return {
5
+ call: (method, input) => getClient().call(method, input),
6
+ async uploadFile(sessionId, file) {
7
+ const formData = new FormData();
8
+ formData.append('file', file);
9
+ const client = getClient();
10
+ const baseUrl = client.getBaseUrl();
11
+ const projectId = client.getProjectId();
12
+ let url = `${baseUrl}/sessions/${sessionId}/upload`;
13
+ if (projectId) {
14
+ url += `?project=${encodeURIComponent(projectId)}`;
15
+ }
16
+ const response = await fetch(url, {
17
+ method: 'POST',
18
+ body: formData,
19
+ credentials: 'include',
20
+ });
21
+ if (!response.ok) {
22
+ const error = await response.json();
23
+ throw new Error(error.error?.message || 'Upload failed');
24
+ }
25
+ return response.json();
26
+ },
27
+ };
28
+ }
29
+ let rpcClient = new RpcClient('');
30
+ export function configureApiBaseUrl(url) {
31
+ const projectId = rpcClient.getProjectId();
32
+ rpcClient = new RpcClient(url);
33
+ if (projectId) {
34
+ rpcClient.setProjectId(projectId);
35
+ }
36
+ }
37
+ export function getApiBaseUrl() {
38
+ return rpcClient.getBaseUrl();
39
+ }
40
+ export function configureProjectId(projectId) {
41
+ rpcClient.setProjectId(projectId);
42
+ }
43
+ export function createApiClient(baseUrl = '') {
44
+ const client = new RpcClient(baseUrl);
45
+ return createApiClientFromRpc(() => client);
46
+ }
47
+ export const api = createApiClientFromRpc(() => rpcClient);
48
+ export function useApiError(error) {
49
+ if (error instanceof RpcError) {
50
+ return error.error.message;
51
+ }
52
+ if (error instanceof Error) {
53
+ return error.message;
54
+ }
55
+ return null;
56
+ }
57
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGxD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAA;AAQ9B,SAAS,sBAAsB,CAAC,SAA0B;IACzD,OAAO;QACN,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;QACxD,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI;YAC/B,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAA;YAC/B,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YAE7B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;YAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;YACnC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAA;YACvC,IAAI,GAAG,GAAG,GAAG,OAAO,aAAa,SAAS,SAAS,CAAA;YACnD,IAAI,SAAS,EAAE,CAAC;gBACf,GAAG,IAAI,YAAY,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAA;YACnD,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBACjC,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,SAAS;aACtB,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAClB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAsC,CAAA;gBACvE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,IAAI,eAAe,CAAC,CAAA;YACzD,CAAC;YAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;QACvB,CAAC;KACD,CAAA;AACF,CAAC;AAED,IAAI,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,CAAA;AAEjC,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC9C,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,EAAE,CAAA;IAC1C,SAAS,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAA;IAC9B,IAAI,SAAS,EAAE,CAAC;QACf,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;IAClC,CAAC;AACF,CAAC;AAED,MAAM,UAAU,aAAa;IAC5B,OAAO,SAAS,CAAC,UAAU,EAAE,CAAA;AAC9B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAwB;IAC1D,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;AAClC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE;IACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,CAAA;IACrC,OAAO,sBAAsB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAc,sBAAsB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;AAErE,MAAM,UAAU,WAAW,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAA;IAC3B,CAAC;IACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC,OAAO,CAAA;IACrB,CAAC;IACD,OAAO,IAAI,CAAA;AACZ,CAAC"}
@@ -1,2 +1,3 @@
1
1
  import type { Result, RpcErrorInfo } from '@roj-ai/shared/rpc';
2
2
  export declare function unwrap<T>(result: Result<T, RpcErrorInfo>): T;
3
+ //# sourceMappingURL=unwrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unwrap.d.ts","sourceRoot":"","sources":["../../src/api/unwrap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE9D,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,CAG5D"}
@@ -0,0 +1,7 @@
1
+ import { RpcError } from '@roj-ai/shared/rpc';
2
+ export function unwrap(result) {
3
+ if (result.ok)
4
+ return result.value;
5
+ throw new RpcError(0, result.error);
6
+ }
7
+ //# sourceMappingURL=unwrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unwrap.js","sourceRoot":"","sources":["../../src/api/unwrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAG7C,MAAM,UAAU,MAAM,CAAI,MAA+B;IACxD,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO,MAAM,CAAC,KAAK,CAAA;IAClC,MAAM,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;AACpC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -7,3 +7,4 @@
7
7
  export { api, configureApiBaseUrl, createApiClient, getApiBaseUrl, configureProjectId, RpcClient, RpcError, useApiError, } from './api/client';
8
8
  export type { ApiClient } from './api/client';
9
9
  export { unwrap } from './api/unwrap';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACN,GAAG,EACH,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,WAAW,GACX,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @roj-ai/client
3
+ *
4
+ * Vanilla TypeScript client for the roj agent server. No React — React hooks
5
+ * and chat components live in `@roj-ai/client-react`.
6
+ */
7
+ export { api, configureApiBaseUrl, createApiClient, getApiBaseUrl, configureProjectId, RpcClient, RpcError, useApiError, } from './api/client';
8
+ export { unwrap } from './api/unwrap';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACN,GAAG,EACH,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,WAAW,GACX,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA"}
@@ -4,3 +4,4 @@ export declare class RojApiError extends Error {
4
4
  readonly type: string;
5
5
  constructor(error: RpcError);
6
6
  }
7
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/platform/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEhD,qBAAa,WAAY,SAAQ,KAAK;aAGT,KAAK,EAAE,QAAQ;IAF3C,SAAgB,IAAI,EAAE,MAAM,CAAA;gBAEA,KAAK,EAAE,QAAQ;CAK3C"}
@@ -0,0 +1,20 @@
1
+ export class RojApiError extends Error {
2
+ constructor(error) {
3
+ super(error.message);
4
+ Object.defineProperty(this, "error", {
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true,
8
+ value: error
9
+ });
10
+ Object.defineProperty(this, "type", {
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true,
14
+ value: void 0
15
+ });
16
+ this.name = 'RojApiError';
17
+ this.type = error.type;
18
+ }
19
+ }
20
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/platform/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,WAAY,SAAQ,KAAK;IAGrC,YAA4B,KAAe;QAC1C,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QADT;;;;mBAAgB,KAAK;WAAU;QAF3B;;;;;WAAY;QAI3B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAA;QACzB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;IACvB,CAAC;CACD"}
@@ -20,5 +20,6 @@ export type { SandboxState } from './sandbox-state';
20
20
  export { buildPreviewUrl, buildWsUrl, buildApiBaseUrl, instanceIdToHex } from './urls';
21
21
  export type { BuildPreviewUrlOptions, BuildWsUrlOptions } from './urls';
22
22
  export { createRojClient } from './rest-client';
23
- export type { RojClient, RojClientOptions } from './rest-client';
23
+ export type { RojClient, RojClientOptions, SessionRpcInput } from './rest-client';
24
24
  export { RojApiError } from './errors';
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACxD,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC/G,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAG5E,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3C,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACpE,mBAAmB,WAAW,CAAA;AAE9B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAC7E,mBAAmB,oBAAoB,CAAA;AAGvC,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAGnD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AACtF,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAGvE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAGjF,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @roj-ai/client/platform
3
+ *
4
+ * Client SDK for the roj platform REST API. Works against both the full
5
+ * platform (Cloudflare worker) and the standalone server.
6
+ */
7
+ // Generic RPC framework
8
+ export { defineMethods, method } from './rpc-definition';
9
+ export { createRpcClient } from './rpc-client';
10
+ export { createRpcRouter } from './rpc-server';
11
+ // Platform method contracts
12
+ export { platformMethods } from './methods';
13
+ export { instanceMethods } from './instance-methods';
14
+ // URL builders
15
+ export { buildPreviewUrl, buildWsUrl, buildApiBaseUrl, instanceIdToHex } from './urls';
16
+ // REST client
17
+ export { createRojClient } from './rest-client';
18
+ // Errors
19
+ export { RojApiError } from './errors';
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/platform/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAwB;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAG9C,4BAA4B;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAI3C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAOpD,eAAe;AACf,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAGtF,cAAc;AACd,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAG/C,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA"}
@@ -92,3 +92,4 @@ export declare const instanceMethods: {
92
92
  };
93
93
  export type InstanceMethods = typeof instanceMethods;
94
94
  export type InstanceMethodName = keyof InstanceMethods;
95
+ //# sourceMappingURL=instance-methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-methods.d.ts","sourceRoot":"","sources":["../../src/platform/instance-methods.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAMzE,MAAM,MAAM,0BAA0B,GAAG,EAAE,CAAA;AAC3C,MAAM,WAAW,2BAA2B;IAC3C,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,yBAAyB;IACzC,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,0BAA0B,GAAG,EAAE,CAAA;AAE3C,MAAM,WAAW,6BAA6B;IAC7C,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,yBAAyB;IACzC,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,yBAAyB;IACzC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,0BAA0B;IAC1C,OAAO,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,2BAA2B;IAC3C,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,iCAAiC;IACjD,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,kCAAkC;IAClD,KAAK,EAAE,OAAO,CAAA;CACd;AAMD,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,2BAA2B;IAC3C,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,yBAAyB,GAAG,EAAE,CAAA;AAC1C,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,CAAA;QACV,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;QACvB,MAAM,EAAE,MAAM,CAAA;QACd,SAAS,EAAE,MAAM,CAAA;KACjB,CAAC,CAAA;CACF;AAED,MAAM,WAAW,2BAA2B;IAC3C,SAAS,EAAE,MAAM,CAAA;CACjB;AAMD,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,2BAA2B;IAC3C,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAClB;AAED,MAAM,WAAW,2BAA2B;IAC3C,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,EAAE,KAAK,CAAC;QACf,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACZ,CAAC,CAAA;CACF;AAED,MAAM,WAAW,2BAA2B;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACb;AAMD,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,OAAO,CAAA;CACX;AAMD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;CAsB1B,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAA;AACpD,MAAM,MAAM,kBAAkB,GAAG,MAAM,eAAe,CAAA"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Instance-scoped RPC method definitions.
3
+ *
4
+ * These methods are called from the SPA via POST /api/v1/instances/:id/rpc
5
+ * with instance token or cookie auth. The instance is already resolved by the route,
6
+ * so inputs do NOT contain instanceId.
7
+ *
8
+ * Shared between worker (server) and client SDK.
9
+ */
10
+ import { defineMethods, method } from './rpc-definition';
11
+ // ============================================================================
12
+ // Method registry
13
+ // ============================================================================
14
+ export const instanceMethods = defineMethods({
15
+ // Sandbox
16
+ createSandbox: method(),
17
+ pauseSandbox: method(),
18
+ resumeSandbox: method(),
19
+ terminateSandbox: method(),
20
+ restartAgent: method(),
21
+ getAgentLogs: method(),
22
+ execInSandbox: method(),
23
+ validateSandboxToken: method(),
24
+ // Sessions
25
+ createSession: method(),
26
+ listSessions: method(),
27
+ publishSession: method(),
28
+ // Services
29
+ getServiceUrl: method(),
30
+ getServiceUrls: method(),
31
+ // Idempotent sandbox access
32
+ ensureSandbox: method(),
33
+ });
34
+ //# sourceMappingURL=instance-methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-methods.js","sourceRoot":"","sources":["../../src/platform/instance-methods.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAkHxD,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;IAC5C,UAAU;IACV,aAAa,EAAE,MAAM,EAA2D;IAChF,YAAY,EAAE,MAAM,EAA+C;IACnE,aAAa,EAAE,MAAM,EAAgD;IACrE,gBAAgB,EAAE,MAAM,EAAmD;IAC3E,YAAY,EAAE,MAAM,EAA+C;IACnE,YAAY,EAAE,MAAM,EAAiD;IACrE,aAAa,EAAE,MAAM,EAA2D;IAChF,oBAAoB,EAAE,MAAM,EAAyE;IAErG,WAAW;IACX,aAAa,EAAE,MAAM,EAA2D;IAChF,YAAY,EAAE,MAAM,EAAyD;IAC7E,cAAc,EAAE,MAAM,EAAqD;IAE3E,WAAW;IACX,aAAa,EAAE,MAAM,EAA2D;IAChF,cAAc,EAAE,MAAM,EAA6D;IAEnF,4BAA4B;IAC5B,aAAa,EAAE,MAAM,EAAmC;CACxD,CAAC,CAAA"}
@@ -115,10 +115,22 @@ export interface CreateInstanceTokenInput {
115
115
  origin?: string;
116
116
  expiresIn?: number;
117
117
  meta?: Record<string, unknown>;
118
+ /**
119
+ * Service codes (e.g. ['dev']) for which the platform should also build a
120
+ * ready-to-use preview URL with the freshly minted token baked in.
121
+ * Saves callers from having to know `baseDomain` or compose the URL.
122
+ */
123
+ previewServiceCodes?: string[];
118
124
  }
119
125
  export interface CreateInstanceTokenOutput {
120
126
  token: string;
121
127
  expiresAt: string;
128
+ /**
129
+ * Preview URLs keyed by service code, populated when `previewServiceCodes`
130
+ * was set on the request. Each URL carries the token in `?token=` and is
131
+ * suitable for direct use as an iframe `src`.
132
+ */
133
+ previewUrls?: Record<string, string>;
122
134
  }
123
135
  export interface ListBundlesInput {
124
136
  limit?: number;
@@ -237,6 +249,27 @@ export interface GetServiceUrlInput {
237
249
  export interface GetServiceUrlOutput {
238
250
  url: string | null;
239
251
  }
252
+ /**
253
+ * Which file namespace inside the session to read from.
254
+ * - `workspace` — the user-facing workspace dir produced by session plugins (e.g. `dist/Course.zip`).
255
+ * - `session` — internal session storage under the SDK's `dataPath/sessions/{sessionId}`.
256
+ */
257
+ export type SessionFileScope = 'workspace' | 'session';
258
+ export interface CreateSessionFileDownloadUrlInput {
259
+ instanceId: string;
260
+ sessionId: string;
261
+ scope: SessionFileScope;
262
+ /** Scope-relative path (no leading slash). Path traversal (`..`) is rejected. */
263
+ path: string;
264
+ /** TTL in seconds. Default 300, max 3600. */
265
+ ttlSeconds?: number;
266
+ }
267
+ export interface CreateSessionFileDownloadUrlOutput {
268
+ /** Signed, time-limited URL serving the file's bytes. */
269
+ url: string;
270
+ /** ISO 8601 expiry of the signed URL. */
271
+ expiresAt: string;
272
+ }
240
273
  export declare const platformMethods: {
241
274
  'instances.create': import("./rpc-definition").MethodDef<CreateInstanceInput, CreateInstanceOutput>;
242
275
  'instances.get': import("./rpc-definition").MethodDef<GetInstanceInput, GetInstanceOutput>;
@@ -248,6 +281,7 @@ export declare const platformMethods: {
248
281
  'sessions.publish': import("./rpc-definition").MethodDef<PublishSessionInput, PublishSessionOutput>;
249
282
  'tokens.create': import("./rpc-definition").MethodDef<CreateInstanceTokenInput, CreateInstanceTokenOutput>;
250
283
  'services.getUrl': import("./rpc-definition").MethodDef<GetServiceUrlInput, GetServiceUrlOutput>;
284
+ 'sessionFiles.createDownloadUrl': import("./rpc-definition").MethodDef<CreateSessionFileDownloadUrlInput, CreateSessionFileDownloadUrlOutput>;
251
285
  'bundles.list': import("./rpc-definition").MethodDef<ListBundlesInput, ListBundlesOutput>;
252
286
  'bundles.delete': import("./rpc-definition").MethodDef<DeleteBundleInput, DeleteBundleOutput>;
253
287
  'resources.create': import("./rpc-definition").MethodDef<CreateResourceInput, CreateResourceOutput>;
@@ -258,3 +292,4 @@ export declare const platformMethods: {
258
292
  };
259
293
  export type PlatformMethods = typeof platformMethods;
260
294
  export type PlatformMethodName = keyof PlatformMethods;
295
+ //# sourceMappingURL=methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/platform/methods.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Platform RPC method definitions.
3
+ *
4
+ * Single source of truth for all platform API method types.
5
+ * Shared between worker (server) and client SDK.
6
+ */
7
+ import { defineMethods, method } from './rpc-definition';
8
+ // ============================================================================
9
+ // Method registry
10
+ // ============================================================================
11
+ export const platformMethods = defineMethods({
12
+ // Instances
13
+ 'instances.create': method(),
14
+ 'instances.get': method(),
15
+ 'instances.list': method(),
16
+ 'instances.status': method(),
17
+ 'instances.archive': method(),
18
+ // Sessions
19
+ 'sessions.create': method(),
20
+ 'sessions.list': method(),
21
+ 'sessions.publish': method(),
22
+ // Tokens
23
+ 'tokens.create': method(),
24
+ // Services
25
+ 'services.getUrl': method(),
26
+ // Session files (signed-URL gateway in front of SDK's session/workspace + session/files routes)
27
+ 'sessionFiles.createDownloadUrl': method(),
28
+ // Bundles
29
+ 'bundles.list': method(),
30
+ 'bundles.delete': method(),
31
+ // Resources
32
+ 'resources.create': method(),
33
+ 'resources.addRevision': method(),
34
+ 'resources.get': method(),
35
+ 'resources.list': method(),
36
+ 'resources.delete': method(),
37
+ });
38
+ //# sourceMappingURL=methods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.js","sourceRoot":"","sources":["../../src/platform/methods.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAoVxD,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;IAC5C,YAAY;IACZ,kBAAkB,EAAE,MAAM,EAA6C;IACvE,eAAe,EAAE,MAAM,EAAuC;IAC9D,gBAAgB,EAAE,MAAM,EAA2C;IACnE,kBAAkB,EAAE,MAAM,EAAmD;IAC7E,mBAAmB,EAAE,MAAM,EAA+C;IAE1E,WAAW;IACX,iBAAiB,EAAE,MAAM,EAA2C;IACpE,eAAe,EAAE,MAAM,EAAyC;IAChE,kBAAkB,EAAE,MAAM,EAA6C;IAEvE,SAAS;IACT,eAAe,EAAE,MAAM,EAAuD;IAE9E,WAAW;IACX,iBAAiB,EAAE,MAAM,EAA2C;IAEpE,gGAAgG;IAChG,gCAAgC,EAAE,MAAM,EAAyE;IAEjH,UAAU;IACV,cAAc,EAAE,MAAM,EAAuC;IAC7D,gBAAgB,EAAE,MAAM,EAAyC;IAEjE,YAAY;IACZ,kBAAkB,EAAE,MAAM,EAA6C;IACvE,uBAAuB,EAAE,MAAM,EAAuD;IACtF,eAAe,EAAE,MAAM,EAAuC;IAC9D,gBAAgB,EAAE,MAAM,EAA2C;IACnE,kBAAkB,EAAE,MAAM,EAA6C;CACvE,CAAC,CAAA"}
@@ -1,10 +1,16 @@
1
- import type { CreateInstanceInput, CreateInstanceOutput, GetInstanceOutput, GetInstanceStatusOutput, ListInstancesInput, ListInstancesOutput, ArchiveInstanceOutput, CreateSessionInput, CreateSessionOutput, ListSessionsOutput, PublishSessionInput, PublishSessionOutput, CreateInstanceTokenInput, CreateInstanceTokenOutput, ListBundlesInput, ListBundlesOutput, DeleteBundleOutput, CreateResourceInput, CreateResourceOutput, AddResourceRevisionInput, AddResourceRevisionOutput, GetResourceInput, GetResourceOutput, ListResourcesInput, ListResourcesOutput, DeleteResourceOutput } from './methods';
1
+ import type { CreateInstanceInput, CreateInstanceOutput, GetInstanceOutput, GetInstanceStatusOutput, ListInstancesInput, ListInstancesOutput, ArchiveInstanceOutput, CreateSessionInput, CreateSessionOutput, ListSessionsOutput, PublishSessionInput, PublishSessionOutput, CreateInstanceTokenInput, CreateInstanceTokenOutput, CreateSessionFileDownloadUrlInput, CreateSessionFileDownloadUrlOutput, ListBundlesInput, ListBundlesOutput, DeleteBundleOutput, CreateResourceInput, CreateResourceOutput, AddResourceRevisionInput, AddResourceRevisionOutput, GetResourceInput, GetResourceOutput, ListResourcesInput, ListResourcesOutput, DeleteResourceOutput } from './methods';
2
2
  export interface RojClientOptions {
3
3
  /** Platform URL (e.g. https://roj.example.com) */
4
4
  url: string;
5
5
  /** Platform API key */
6
6
  apiKey: string;
7
7
  }
8
+ export interface SessionRpcInput {
9
+ instanceId: string;
10
+ sessionId: string;
11
+ method: string;
12
+ input?: Record<string, unknown>;
13
+ }
8
14
  export interface RojClient {
9
15
  instances: {
10
16
  create(input: CreateInstanceInput): Promise<CreateInstanceOutput>;
@@ -17,10 +23,28 @@ export interface RojClient {
17
23
  create(input: CreateSessionInput): Promise<CreateSessionOutput>;
18
24
  list(instanceId: string): Promise<ListSessionsOutput>;
19
25
  publish(input: PublishSessionInput): Promise<PublishSessionOutput>;
26
+ /**
27
+ * Call a plugin/session RPC method on a running session.
28
+ *
29
+ * Auto-mints and caches an instance token; the cached token is reused until
30
+ * its expiry minus a small leeway. Suitable for server-to-server callers
31
+ * that don't have a browser cookie or pre-existing instance token.
32
+ */
33
+ rpc<T = unknown>(input: SessionRpcInput): Promise<T>;
20
34
  };
21
35
  tokens: {
22
36
  create(input: CreateInstanceTokenInput): Promise<CreateInstanceTokenOutput>;
23
37
  };
38
+ sessionFiles: {
39
+ /**
40
+ * Mint a short-lived signed URL that streams the bytes of a session-bound file
41
+ * back to the caller. Use after a session plugin has produced an artifact
42
+ * (e.g. workspace `dist/Course.zip`) and the caller wants to fetch it without
43
+ * routing through the dev preview proxy. `scope` selects between the workspace
44
+ * dir and the SDK's session storage.
45
+ */
46
+ createDownloadUrl(input: CreateSessionFileDownloadUrlInput): Promise<CreateSessionFileDownloadUrlOutput>;
47
+ };
24
48
  bundles: {
25
49
  list(input?: ListBundlesInput): Promise<ListBundlesOutput>;
26
50
  delete(input: {
@@ -47,3 +71,4 @@ export interface RojClient {
47
71
  };
48
72
  }
49
73
  export declare function createRojClient(options: RojClientOptions): RojClient;
74
+ //# sourceMappingURL=rest-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-client.d.ts","sourceRoot":"","sources":["../../src/platform/rest-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import { createRpcClient } from './rpc-client';
2
+ import { RojApiError } from './errors';
3
+ // Re-mint instance tokens this many milliseconds before their server-stated expiry.
4
+ // Covers both clock skew between client and server and the latency of an in-flight
5
+ // session RPC that started just before expiry.
6
+ const TOKEN_REFRESH_LEEWAY_MS = 30000;
7
+ export function createRojClient(options) {
8
+ const rpc = createRpcClient(`${options.url}/api/v1`, {
9
+ headers: { Authorization: `Bearer ${options.apiKey}` },
10
+ });
11
+ async function call(method, input) {
12
+ const result = await rpc.call(method, input);
13
+ if (!result.ok)
14
+ throw new RojApiError(result.error);
15
+ return result.value;
16
+ }
17
+ const instanceTokenCache = new Map();
18
+ const inflightTokenMint = new Map();
19
+ async function getInstanceToken(instanceId) {
20
+ const cached = instanceTokenCache.get(instanceId);
21
+ if (cached && cached.expiresAtMs - TOKEN_REFRESH_LEEWAY_MS > Date.now()) {
22
+ return cached.token;
23
+ }
24
+ const inflight = inflightTokenMint.get(instanceId);
25
+ if (inflight)
26
+ return inflight;
27
+ const promise = (async () => {
28
+ try {
29
+ const fresh = await call('tokens.create', { instanceId });
30
+ instanceTokenCache.set(instanceId, {
31
+ token: fresh.token,
32
+ expiresAtMs: new Date(fresh.expiresAt).getTime(),
33
+ });
34
+ return fresh.token;
35
+ }
36
+ finally {
37
+ inflightTokenMint.delete(instanceId);
38
+ }
39
+ })();
40
+ inflightTokenMint.set(instanceId, promise);
41
+ return promise;
42
+ }
43
+ async function callSessionRpc(input, retriedAfter401 = false) {
44
+ const token = await getInstanceToken(input.instanceId);
45
+ const url = `${options.url}/api/v1/instances/${input.instanceId}/sessions/${input.sessionId}/rpc`;
46
+ const response = await fetch(url, {
47
+ method: 'POST',
48
+ headers: {
49
+ 'Content-Type': 'application/json',
50
+ Authorization: `Bearer ${token}`,
51
+ },
52
+ body: JSON.stringify({ method: input.method, input: input.input ?? {} }),
53
+ });
54
+ // Token may have been revoked or rotated server-side before its stated `expiresAt`.
55
+ // Evict the cache and retry once with a freshly minted token.
56
+ if (response.status === 401 && !retriedAfter401) {
57
+ instanceTokenCache.delete(input.instanceId);
58
+ return callSessionRpc(input, true);
59
+ }
60
+ const body = await response.json().catch(() => null);
61
+ if (!response.ok || !body || body.ok === false) {
62
+ const error = body?.error ?? { type: 'transport_error', message: `HTTP ${response.status}` };
63
+ throw new RojApiError(error);
64
+ }
65
+ return body.value;
66
+ }
67
+ return {
68
+ instances: {
69
+ create: (input) => call('instances.create', input),
70
+ get: (instanceId) => call('instances.get', { instanceId }),
71
+ getStatus: (instanceId) => call('instances.status', { instanceId }),
72
+ list: (input) => call('instances.list', input ?? {}),
73
+ archive: (instanceId) => call('instances.archive', { instanceId }),
74
+ },
75
+ sessions: {
76
+ create: (input) => call('sessions.create', input),
77
+ list: (instanceId) => call('sessions.list', { instanceId }),
78
+ publish: (input) => call('sessions.publish', input),
79
+ rpc: (input) => callSessionRpc(input),
80
+ },
81
+ tokens: {
82
+ create: (input) => call('tokens.create', input),
83
+ },
84
+ sessionFiles: {
85
+ createDownloadUrl: (input) => call('sessionFiles.createDownloadUrl', input),
86
+ },
87
+ bundles: {
88
+ list: (input) => call('bundles.list', input ?? {}),
89
+ delete: (input) => call('bundles.delete', input),
90
+ },
91
+ files: {
92
+ upload: async (file, filename) => {
93
+ const formData = new FormData();
94
+ formData.append('file', file, filename);
95
+ const response = await fetch(`${options.url}/api/v1/files/upload`, {
96
+ method: 'POST',
97
+ headers: { Authorization: `Bearer ${options.apiKey}` },
98
+ body: formData,
99
+ });
100
+ if (!response.ok) {
101
+ const body = await response.json().catch(() => ({ message: response.statusText }));
102
+ throw new RojApiError({ type: 'http_error', message: body.error ?? body.message ?? response.statusText });
103
+ }
104
+ return response.json();
105
+ },
106
+ },
107
+ resources: {
108
+ create: (input) => call('resources.create', input),
109
+ addRevision: (input) => call('resources.addRevision', input),
110
+ get: (input) => call('resources.get', input),
111
+ list: (input) => call('resources.list', input ?? {}),
112
+ delete: (resourceId) => call('resources.delete', { resourceId }),
113
+ },
114
+ };
115
+ }
116
+ //# sourceMappingURL=rest-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-client.js","sourceRoot":"","sources":["../../src/platform/rest-client.ts"],"names":[],"mappings":"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"}
@@ -24,3 +24,4 @@ export type RpcResult<T> = {
24
24
  error: RpcError;
25
25
  };
26
26
  export declare function createRpcClient<Methods extends Record<string, MethodDef>>(baseUrl: string, options?: RpcClientOptions): RpcClient<Methods>;
27
+ //# sourceMappingURL=rpc-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-client.d.ts","sourceRoot":"","sources":["../../src/platform/rpc-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAe,MAAM,kBAAkB,CAAA;AAEnG,MAAM,WAAW,gBAAgB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,WAAW,CAAC,EAAE,kBAAkB,CAAA;CAChC;AAED,MAAM,WAAW,SAAS,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;IACnE,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,OAAO,EACpC,MAAM,EAAE,CAAC,EACT,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,GAC5B,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;CAC/C;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,IACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAA;AAEjC,wBAAgB,eAAe,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACxE,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,gBAAgB,GACxB,SAAS,CAAC,OAAO,CAAC,CAmCpB"}
@@ -0,0 +1,30 @@
1
+ export function createRpcClient(baseUrl, options) {
2
+ return {
3
+ async call(method, input) {
4
+ const response = await fetch(`${baseUrl}/rpc`, {
5
+ method: 'POST',
6
+ headers: {
7
+ 'Content-Type': 'application/json',
8
+ ...options?.headers,
9
+ },
10
+ credentials: options?.credentials,
11
+ body: JSON.stringify({ method, input }),
12
+ });
13
+ const data = (await response.json());
14
+ if (!response.ok) {
15
+ return {
16
+ ok: false,
17
+ error: data.error ?? { type: 'transport_error', message: `HTTP ${response.status}` },
18
+ };
19
+ }
20
+ if (data.ok) {
21
+ return { ok: true, value: data.value };
22
+ }
23
+ return {
24
+ ok: false,
25
+ error: data.error ?? { type: 'unknown_error', message: 'Unknown error' },
26
+ };
27
+ },
28
+ };
29
+ }
30
+ //# sourceMappingURL=rpc-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-client.js","sourceRoot":"","sources":["../../src/platform/rpc-client.ts"],"names":[],"mappings":"AA4BA,MAAM,UAAU,eAAe,CAC9B,OAAe,EACf,OAA0B;IAE1B,OAAO;QACN,KAAK,CAAC,IAAI,CACT,MAAS,EACT,KAA8B;YAE9B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,MAAM,EAAE;gBAC9C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACR,cAAc,EAAE,kBAAkB;oBAClC,GAAG,OAAO,EAAE,OAAO;iBACnB;gBACD,WAAW,EAAE,OAAO,EAAE,WAAW;gBACjC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;aACvC,CAAC,CAAA;YAEF,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAgB,CAAA;YAEnD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAClB,OAAO;oBACN,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE;iBACpF,CAAA;YACF,CAAC;YAED,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gBACb,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAiC,EAAE,CAAA;YACnE,CAAC;YAED,OAAO;gBACN,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe,EAAE;aACxE,CAAA;QACF,CAAC;KACD,CAAA;AACF,CAAC"}
@@ -37,3 +37,4 @@ export interface RpcError {
37
37
  message: string;
38
38
  details?: unknown;
39
39
  }
40
+ //# sourceMappingURL=rpc-definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-definition.d.ts","sourceRoot":"","sources":["../../src/platform/rpc-definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IAClD,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAClB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;CACnB;AAED,oEAAoE;AACpE,wBAAgB,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAE9C;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAEhF;AAED,6CAA6C;AAC7C,MAAM,MAAM,WAAW,CACtB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACzC,CAAC,SAAS,MAAM,OAAO,IACpB,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;AAExB,8CAA8C;AAC9C,MAAM,MAAM,YAAY,CACvB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACzC,CAAC,SAAS,MAAM,OAAO,IACpB,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AAEzB,4BAA4B;AAC5B,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACpD,MAAM,EAAE,CAAC,CAAA;IACT,KAAK,EAAE,OAAO,CAAA;CACd;AAED,6BAA6B;AAC7B,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACvC,EAAE,EAAE,OAAO,CAAA;IACX,KAAK,CAAC,EAAE,CAAC,CAAA;IACT,KAAK,CAAC,EAAE,QAAQ,CAAA;CAChB;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Type-safe RPC definition system.
3
+ * No external dependencies — just TypeScript types + minimal runtime.
4
+ *
5
+ * Usage:
6
+ * const methods = defineMethods({
7
+ * 'instances.create': method<CreateInput, CreateOutput>(),
8
+ * 'sessions.list': method<ListInput, ListOutput>(),
9
+ * })
10
+ */
11
+ /** Define a method type. Zero runtime cost — just a type marker. */
12
+ export function method() {
13
+ return {};
14
+ }
15
+ /** Define a set of methods. Returns the definition object as-is (typed). */
16
+ export function defineMethods(methods) {
17
+ return methods;
18
+ }
19
+ //# sourceMappingURL=rpc-definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-definition.js","sourceRoot":"","sources":["../../src/platform/rpc-definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,oEAAoE;AACpE,MAAM,UAAU,MAAM;IACrB,OAAO,EAAqB,CAAA;AAC7B,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAsC,OAAU;IAC5E,OAAO,OAAO,CAAA;AACf,CAAC"}
@@ -19,3 +19,4 @@ export interface RpcRouter<Ctx> {
19
19
  handle(request: RpcRequest, ctx: Ctx): Promise<RpcResponse>;
20
20
  }
21
21
  export declare function createRpcRouter<Methods extends Record<string, MethodDef>, Ctx>(_methods: Methods, handlers: MethodHandlers<Methods, Ctx>): RpcRouter<Ctx>;
22
+ //# sourceMappingURL=rpc-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-server.d.ts","sourceRoot":"","sources":["../../src/platform/rpc-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAY,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE/G,MAAM,MAAM,aAAa,CACxB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACzC,CAAC,SAAS,MAAM,OAAO,EACvB,GAAG,IACA,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;AAEnF,MAAM,MAAM,cAAc,CACzB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACzC,GAAG,IACA;KACF,CAAC,IAAI,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,CAAC;CACpD,CAAA;AAED,MAAM,WAAW,SAAS,CAAC,GAAG;IAC7B,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;CAC3D;AAED,wBAAgB,eAAe,CAC9B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACzC,GAAG,EAEH,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,GACpC,SAAS,CAAC,GAAG,CAAC,CAsBhB"}
@@ -0,0 +1,24 @@
1
+ export function createRpcRouter(_methods, handlers) {
2
+ return {
3
+ async handle(request, ctx) {
4
+ const handler = handlers[request.method];
5
+ if (!handler) {
6
+ return {
7
+ ok: false,
8
+ error: { type: 'method_not_found', message: `Unknown method: ${request.method}` },
9
+ };
10
+ }
11
+ try {
12
+ const result = await handler(request.input, ctx);
13
+ return { ok: true, value: result };
14
+ }
15
+ catch (error) {
16
+ const rpcError = error instanceof Error
17
+ ? { type: 'handler_error', message: error.message }
18
+ : { type: 'unknown_error', message: String(error) };
19
+ return { ok: false, error: rpcError };
20
+ }
21
+ },
22
+ };
23
+ }
24
+ //# sourceMappingURL=rpc-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-server.js","sourceRoot":"","sources":["../../src/platform/rpc-server.ts"],"names":[],"mappings":"AA+BA,MAAM,UAAU,eAAe,CAI9B,QAAiB,EACjB,QAAsC;IAEtC,OAAO;QACN,KAAK,CAAC,MAAM,CAAC,OAAmB,EAAE,GAAQ;YACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAuB,CAAC,CAAA;YACzD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,OAAO;oBACN,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,mBAAmB,OAAO,CAAC,MAAM,EAAE,EAAE;iBACjF,CAAA;YACF,CAAC;YAED,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,KAAY,EAAE,GAAG,CAAC,CAAA;gBACvD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,QAAQ,GAAa,KAAK,YAAY,KAAK;oBAChD,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;oBACnD,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;gBACpD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;YACtC,CAAC;QACF,CAAC;KACD,CAAA;AACF,CAAC"}
@@ -1 +1,2 @@
1
1
  export type SandboxState = 'stopped' | 'starting' | 'running' | 'pausing' | 'paused' | 'failed';
2
+ //# sourceMappingURL=sandbox-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-state.d.ts","sourceRoot":"","sources":["../../src/platform/sandbox-state.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sandbox-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-state.js","sourceRoot":"","sources":["../../src/platform/sandbox-state.ts"],"names":[],"mappings":""}
@@ -32,3 +32,4 @@ export declare function buildWsUrl({ platformUrl, instanceId, sessionId, token }
32
32
  * Build the RPC base URL for a roj instance.
33
33
  */
34
34
  export declare function buildApiBaseUrl(platformUrl: string, instanceId: string): string;
35
+ //# sourceMappingURL=urls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../src/platform/urls.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,MAAM,WAAW,sBAAsB;IACtC,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,sBAAsB,GAAG,MAAM,CAapH;AAED,MAAM,WAAW,iBAAiB;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACb;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,iBAAiB,GAAG,MAAM,CAMnG;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/E"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Convert an instance UUID to its full 32-char hex representation (no hyphens, lowercase).
3
+ */
4
+ export function instanceIdToHex(instanceId) {
5
+ return instanceId.replace(/-/g, '').toLowerCase();
6
+ }
7
+ /**
8
+ * Build a dev preview URL for a service running in a roj sandbox.
9
+ *
10
+ * Production: https://dev-{slug}-{code}.{baseDomain}/
11
+ * Local dev: {platformUrl}/api/v1/instances/{id}/preview/{code}/
12
+ */
13
+ export function buildPreviewUrl({ instanceId, code, baseDomain, token, platformUrl }) {
14
+ // Cloudflare quick tunnels are already subdomains — can't nest further
15
+ if (baseDomain.includes('trycloudflare.com') && platformUrl) {
16
+ const base = `${platformUrl}/api/v1/instances/${instanceId}/preview/${code}`;
17
+ return token ? `${base}/?token=${encodeURIComponent(token)}` : base;
18
+ }
19
+ // Subdomain-based: dev-{hex}-{code}.{baseDomain}
20
+ // Works on localhost (*.localhost resolves to 127.0.0.1) and production
21
+ const hex = instanceIdToHex(instanceId);
22
+ const protocol = baseDomain.includes('localhost') ? 'http' : 'https';
23
+ const base = `${protocol}://dev-${hex}-${code}.${baseDomain}`;
24
+ return token ? `${base}/?token=${encodeURIComponent(token)}` : base;
25
+ }
26
+ /**
27
+ * Build a WebSocket URL for connecting to a roj instance.
28
+ */
29
+ export function buildWsUrl({ platformUrl, instanceId, sessionId, token }) {
30
+ const url = new URL(`/api/v1/instances/${instanceId}/ws`, platformUrl);
31
+ url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
32
+ url.searchParams.set('token', token);
33
+ url.searchParams.set('sessionId', sessionId);
34
+ return url.toString();
35
+ }
36
+ /**
37
+ * Build the RPC base URL for a roj instance.
38
+ */
39
+ export function buildApiBaseUrl(platformUrl, instanceId) {
40
+ return `${platformUrl}/api/v1/instances/${instanceId}`;
41
+ }
42
+ //# sourceMappingURL=urls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../src/platform/urls.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB;IACjD,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;AAClD,CAAC;AAYD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAA0B;IAC3G,uEAAuE;IACvE,IAAI,UAAU,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,WAAW,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAG,GAAG,WAAW,qBAAqB,UAAU,YAAY,IAAI,EAAE,CAAA;QAC5E,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,WAAW,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACpE,CAAC;IAED,iDAAiD;IACjD,wEAAwE;IACxE,MAAM,GAAG,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;IACvC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IACpE,MAAM,IAAI,GAAG,GAAG,QAAQ,UAAU,GAAG,IAAI,IAAI,IAAI,UAAU,EAAE,CAAA;IAC7D,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,WAAW,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACpE,CAAC;AASD;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAqB;IAC1F,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,qBAAqB,UAAU,KAAK,EAAE,WAAW,CAAC,CAAA;IACtE,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA;IACzD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACpC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAC5C,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAA;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB,EAAE,UAAkB;IACtE,OAAO,GAAG,WAAW,qBAAqB,UAAU,EAAE,CAAA;AACvD,CAAC"}
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@roj-ai/client",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
- "main": "./src/index.ts",
5
+ "main": "./dist/index.js",
6
6
  "exports": {
7
7
  ".": {
8
8
  "types": "./dist/index.d.ts",
9
- "import": "./src/index.ts",
10
- "default": "./src/index.ts"
9
+ "import": "./dist/index.js",
10
+ "default": "./dist/index.js"
11
11
  },
12
12
  "./api": {
13
13
  "types": "./dist/api/client.d.ts",
14
- "import": "./src/api/client.ts",
15
- "default": "./src/api/client.ts"
14
+ "import": "./dist/api/client.js",
15
+ "default": "./dist/api/client.js"
16
16
  },
17
17
  "./platform": {
18
18
  "types": "./dist/platform/index.d.ts",
19
- "import": "./src/platform/index.ts",
20
- "default": "./src/platform/index.ts"
19
+ "import": "./dist/platform/index.js",
20
+ "default": "./dist/platform/index.js"
21
21
  }
22
22
  },
23
23
  "files": [
@@ -40,7 +40,7 @@
40
40
  "type-check": "tsc --noEmit"
41
41
  },
42
42
  "dependencies": {
43
- "@roj-ai/shared": "^0.1.3"
43
+ "@roj-ai/shared": "^0.1.5"
44
44
  },
45
45
  "devDependencies": {
46
46
  "typescript": "5.9.3"
@@ -31,7 +31,7 @@ export type { BuildPreviewUrlOptions, BuildWsUrlOptions } from './urls'
31
31
 
32
32
  // REST client
33
33
  export { createRojClient } from './rest-client'
34
- export type { RojClient, RojClientOptions } from './rest-client'
34
+ export type { RojClient, RojClientOptions, SessionRpcInput } from './rest-client'
35
35
 
36
36
  // Errors
37
37
  export { RojApiError } from './errors'
@@ -151,11 +151,23 @@ export interface CreateInstanceTokenInput {
151
151
  origin?: string
152
152
  expiresIn?: number // token TTL in seconds (default 24h, max 7d)
153
153
  meta?: Record<string, unknown> // custom claims propagated to plugin method caller context
154
+ /**
155
+ * Service codes (e.g. ['dev']) for which the platform should also build a
156
+ * ready-to-use preview URL with the freshly minted token baked in.
157
+ * Saves callers from having to know `baseDomain` or compose the URL.
158
+ */
159
+ previewServiceCodes?: string[]
154
160
  }
155
161
 
156
162
  export interface CreateInstanceTokenOutput {
157
163
  token: string
158
164
  expiresAt: string
165
+ /**
166
+ * Preview URLs keyed by service code, populated when `previewServiceCodes`
167
+ * was set on the request. Each URL carries the token in `?token=` and is
168
+ * suitable for direct use as an iframe `src`.
169
+ */
170
+ previewUrls?: Record<string, string>
159
171
  }
160
172
 
161
173
  // ============================================================================
@@ -304,6 +316,34 @@ export interface GetServiceUrlOutput {
304
316
  url: string | null
305
317
  }
306
318
 
319
+ // ============================================================================
320
+ // Session files
321
+ // ============================================================================
322
+
323
+ /**
324
+ * Which file namespace inside the session to read from.
325
+ * - `workspace` — the user-facing workspace dir produced by session plugins (e.g. `dist/Course.zip`).
326
+ * - `session` — internal session storage under the SDK's `dataPath/sessions/{sessionId}`.
327
+ */
328
+ export type SessionFileScope = 'workspace' | 'session'
329
+
330
+ export interface CreateSessionFileDownloadUrlInput {
331
+ instanceId: string
332
+ sessionId: string
333
+ scope: SessionFileScope
334
+ /** Scope-relative path (no leading slash). Path traversal (`..`) is rejected. */
335
+ path: string
336
+ /** TTL in seconds. Default 300, max 3600. */
337
+ ttlSeconds?: number
338
+ }
339
+
340
+ export interface CreateSessionFileDownloadUrlOutput {
341
+ /** Signed, time-limited URL serving the file's bytes. */
342
+ url: string
343
+ /** ISO 8601 expiry of the signed URL. */
344
+ expiresAt: string
345
+ }
346
+
307
347
  // ============================================================================
308
348
  // Method registry
309
349
  // ============================================================================
@@ -327,6 +367,9 @@ export const platformMethods = defineMethods({
327
367
  // Services
328
368
  'services.getUrl': method<GetServiceUrlInput, GetServiceUrlOutput>(),
329
369
 
370
+ // Session files (signed-URL gateway in front of SDK's session/workspace + session/files routes)
371
+ 'sessionFiles.createDownloadUrl': method<CreateSessionFileDownloadUrlInput, CreateSessionFileDownloadUrlOutput>(),
372
+
330
373
  // Bundles
331
374
  'bundles.list': method<ListBundlesInput, ListBundlesOutput>(),
332
375
  'bundles.delete': method<DeleteBundleInput, DeleteBundleOutput>(),
@@ -16,6 +16,8 @@ import type {
16
16
  PublishSessionOutput,
17
17
  CreateInstanceTokenInput,
18
18
  CreateInstanceTokenOutput,
19
+ CreateSessionFileDownloadUrlInput,
20
+ CreateSessionFileDownloadUrlOutput,
19
21
  ListBundlesInput,
20
22
  ListBundlesOutput,
21
23
  DeleteBundleOutput,
@@ -38,6 +40,13 @@ export interface RojClientOptions {
38
40
  apiKey: string
39
41
  }
40
42
 
43
+ export interface SessionRpcInput {
44
+ instanceId: string
45
+ sessionId: string
46
+ method: string
47
+ input?: Record<string, unknown>
48
+ }
49
+
41
50
  export interface RojClient {
42
51
  instances: {
43
52
  create(input: CreateInstanceInput): Promise<CreateInstanceOutput>
@@ -50,10 +59,28 @@ export interface RojClient {
50
59
  create(input: CreateSessionInput): Promise<CreateSessionOutput>
51
60
  list(instanceId: string): Promise<ListSessionsOutput>
52
61
  publish(input: PublishSessionInput): Promise<PublishSessionOutput>
62
+ /**
63
+ * Call a plugin/session RPC method on a running session.
64
+ *
65
+ * Auto-mints and caches an instance token; the cached token is reused until
66
+ * its expiry minus a small leeway. Suitable for server-to-server callers
67
+ * that don't have a browser cookie or pre-existing instance token.
68
+ */
69
+ rpc<T = unknown>(input: SessionRpcInput): Promise<T>
53
70
  }
54
71
  tokens: {
55
72
  create(input: CreateInstanceTokenInput): Promise<CreateInstanceTokenOutput>
56
73
  }
74
+ sessionFiles: {
75
+ /**
76
+ * Mint a short-lived signed URL that streams the bytes of a session-bound file
77
+ * back to the caller. Use after a session plugin has produced an artifact
78
+ * (e.g. workspace `dist/Course.zip`) and the caller wants to fetch it without
79
+ * routing through the dev preview proxy. `scope` selects between the workspace
80
+ * dir and the SDK's session storage.
81
+ */
82
+ createDownloadUrl(input: CreateSessionFileDownloadUrlInput): Promise<CreateSessionFileDownloadUrlOutput>
83
+ }
57
84
  bundles: {
58
85
  list(input?: ListBundlesInput): Promise<ListBundlesOutput>
59
86
  delete(input: { bundleId?: string; bundleSlug?: string }): Promise<DeleteBundleOutput>
@@ -70,6 +97,16 @@ export interface RojClient {
70
97
  }
71
98
  }
72
99
 
100
+ // Re-mint instance tokens this many milliseconds before their server-stated expiry.
101
+ // Covers both clock skew between client and server and the latency of an in-flight
102
+ // session RPC that started just before expiry.
103
+ const TOKEN_REFRESH_LEEWAY_MS = 30_000
104
+
105
+ interface CachedToken {
106
+ token: string
107
+ expiresAtMs: number
108
+ }
109
+
73
110
  export function createRojClient(options: RojClientOptions): RojClient {
74
111
  const rpc = createRpcClient<PlatformMethods>(`${options.url}/api/v1`, {
75
112
  headers: { Authorization: `Bearer ${options.apiKey}` },
@@ -84,6 +121,56 @@ export function createRojClient(options: RojClientOptions): RojClient {
84
121
  return result.value
85
122
  }
86
123
 
124
+ const instanceTokenCache = new Map<string, CachedToken>()
125
+ const inflightTokenMint = new Map<string, Promise<string>>()
126
+ async function getInstanceToken(instanceId: string): Promise<string> {
127
+ const cached = instanceTokenCache.get(instanceId)
128
+ if (cached && cached.expiresAtMs - TOKEN_REFRESH_LEEWAY_MS > Date.now()) {
129
+ return cached.token
130
+ }
131
+ const inflight = inflightTokenMint.get(instanceId)
132
+ if (inflight) return inflight
133
+ const promise = (async () => {
134
+ try {
135
+ const fresh = await call('tokens.create', { instanceId })
136
+ instanceTokenCache.set(instanceId, {
137
+ token: fresh.token,
138
+ expiresAtMs: new Date(fresh.expiresAt).getTime(),
139
+ })
140
+ return fresh.token
141
+ } finally {
142
+ inflightTokenMint.delete(instanceId)
143
+ }
144
+ })()
145
+ inflightTokenMint.set(instanceId, promise)
146
+ return promise
147
+ }
148
+
149
+ async function callSessionRpc<T>(input: SessionRpcInput, retriedAfter401 = false): Promise<T> {
150
+ const token = await getInstanceToken(input.instanceId)
151
+ const url = `${options.url}/api/v1/instances/${input.instanceId}/sessions/${input.sessionId}/rpc`
152
+ const response = await fetch(url, {
153
+ method: 'POST',
154
+ headers: {
155
+ 'Content-Type': 'application/json',
156
+ Authorization: `Bearer ${token}`,
157
+ },
158
+ body: JSON.stringify({ method: input.method, input: input.input ?? {} }),
159
+ })
160
+ // Token may have been revoked or rotated server-side before its stated `expiresAt`.
161
+ // Evict the cache and retry once with a freshly minted token.
162
+ if (response.status === 401 && !retriedAfter401) {
163
+ instanceTokenCache.delete(input.instanceId)
164
+ return callSessionRpc<T>(input, true)
165
+ }
166
+ const body = await response.json().catch(() => null) as { ok?: boolean; value?: unknown; error?: { type: string; message: string } } | null
167
+ if (!response.ok || !body || body.ok === false) {
168
+ const error = body?.error ?? { type: 'transport_error', message: `HTTP ${response.status}` }
169
+ throw new RojApiError(error)
170
+ }
171
+ return body.value as T
172
+ }
173
+
87
174
  return {
88
175
  instances: {
89
176
  create: (input) => call('instances.create', input),
@@ -96,10 +183,14 @@ export function createRojClient(options: RojClientOptions): RojClient {
96
183
  create: (input) => call('sessions.create', input),
97
184
  list: (instanceId) => call('sessions.list', { instanceId }),
98
185
  publish: (input) => call('sessions.publish', input),
186
+ rpc: (input) => callSessionRpc(input),
99
187
  },
100
188
  tokens: {
101
189
  create: (input) => call('tokens.create', input),
102
190
  },
191
+ sessionFiles: {
192
+ createDownloadUrl: (input) => call('sessionFiles.createDownloadUrl', input),
193
+ },
103
194
  bundles: {
104
195
  list: (input) => call('bundles.list', input ?? {}),
105
196
  delete: (input) => call('bundles.delete', input),