@palgroup/simstream 0.10.0 → 0.12.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/README.md +4 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +15 -1
- package/dist/organization.d.ts +31 -0
- package/dist/organization.js +43 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,10 @@ Completing an upload publishes the build and moves its app's `latest` channel to
|
|
|
53
53
|
`runBuild({ channel: 'com.example.app:latest' })` always opens the newest one. `setChannel(id, 'beta')`
|
|
54
54
|
names others.
|
|
55
55
|
|
|
56
|
+
A session that is already open takes another build without being restarted:
|
|
57
|
+
`installBuild(session.session, { build: other.id })` puts it on that one simulator only — unlike `pushBuild`, which
|
|
58
|
+
goes to every session the key holds.
|
|
59
|
+
|
|
56
60
|
## When there is nothing free
|
|
57
61
|
|
|
58
62
|
`startSession()` throws a `SimStreamError`. The `code` says what to do about it:
|
package/dist/index.d.ts
CHANGED
|
@@ -383,6 +383,17 @@ export declare class SimStream {
|
|
|
383
383
|
* link follows, so a demo and a tester see the same build without anybody reissuing anything.
|
|
384
384
|
*/
|
|
385
385
|
runBuild(ref: BuildRef, opts?: StartOptions): Promise<Session>;
|
|
386
|
+
/**
|
|
387
|
+
* Put a registry build on ONE session that is already open — by id to pin it, or by channel to follow it.
|
|
388
|
+
*
|
|
389
|
+
* ‼️ THIS IS NOT pushBuild. A push goes to every session the key holds, which is right for "a new build landed, show
|
|
390
|
+
* it to whoever is looking" and wrong for a key that serves several people: one of them choosing yesterday's build
|
|
391
|
+
* would replace the app under all the others. The install runs after the answer; watch it land with appStatus.
|
|
392
|
+
*/
|
|
393
|
+
installBuild(session: string, ref: BuildRef, opts?: {
|
|
394
|
+
launch?: boolean;
|
|
395
|
+
mode?: SimMode;
|
|
396
|
+
}): Promise<void>;
|
|
386
397
|
/**
|
|
387
398
|
* A fresh link to a session that is already running.
|
|
388
399
|
*
|
|
@@ -553,4 +564,6 @@ export declare class SimStream {
|
|
|
553
564
|
export { resolveSource, isCertain } from './source';
|
|
554
565
|
export type { SourceAnswer, SourceConfidence } from './source';
|
|
555
566
|
export { SimStreamAdmin } from './admin';
|
|
567
|
+
export { SimStreamOrganization } from './organization';
|
|
568
|
+
export type { OrganizationOptions, CreatedProject } from './organization';
|
|
556
569
|
export type { AdminOptions, Customer } from './admin';
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* separation has stopped being real.
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.SimStreamAdmin = exports.isCertain = exports.resolveSource = exports.SimStream = exports.SimStreamError = void 0;
|
|
15
|
+
exports.SimStreamOrganization = exports.SimStreamAdmin = exports.isCertain = exports.resolveSource = exports.SimStream = exports.SimStreamError = void 0;
|
|
16
16
|
class SimStreamError extends Error {
|
|
17
17
|
code;
|
|
18
18
|
status;
|
|
@@ -218,6 +218,18 @@ class SimStream {
|
|
|
218
218
|
async runBuild(ref, opts = {}) {
|
|
219
219
|
return this.startSession({ ...opts, ...ref });
|
|
220
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Put a registry build on ONE session that is already open — by id to pin it, or by channel to follow it.
|
|
223
|
+
*
|
|
224
|
+
* ‼️ THIS IS NOT pushBuild. A push goes to every session the key holds, which is right for "a new build landed, show
|
|
225
|
+
* it to whoever is looking" and wrong for a key that serves several people: one of them choosing yesterday's build
|
|
226
|
+
* would replace the app under all the others. The install runs after the answer; watch it land with appStatus.
|
|
227
|
+
*/
|
|
228
|
+
async installBuild(session, ref, opts = {}) {
|
|
229
|
+
const res = await this.request('POST', '/api/session/build', { session, ...ref, mode: opts.mode, launch: opts.launch });
|
|
230
|
+
if (res.status !== 200)
|
|
231
|
+
throw await this.errorFor(res);
|
|
232
|
+
}
|
|
221
233
|
/**
|
|
222
234
|
* A fresh link to a session that is already running.
|
|
223
235
|
*
|
|
@@ -506,3 +518,5 @@ Object.defineProperty(exports, "resolveSource", { enumerable: true, get: functio
|
|
|
506
518
|
Object.defineProperty(exports, "isCertain", { enumerable: true, get: function () { return source_1.isCertain; } });
|
|
507
519
|
var admin_1 = require("./admin");
|
|
508
520
|
Object.defineProperty(exports, "SimStreamAdmin", { enumerable: true, get: function () { return admin_1.SimStreamAdmin; } });
|
|
521
|
+
var organization_1 = require("./organization");
|
|
522
|
+
Object.defineProperty(exports, "SimStreamOrganization", { enumerable: true, get: function () { return organization_1.SimStreamOrganization; } });
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An organization's own hand: making the projects its keys belong to.
|
|
3
|
+
*
|
|
4
|
+
* Separate from the customer client for the reason the admin one is: a project's key can run simulators and upload
|
|
5
|
+
* builds for that project, and must never be able to make another project. The organization token can, and nothing
|
|
6
|
+
* but the service that owns the organization should hold it.
|
|
7
|
+
*/
|
|
8
|
+
export interface OrganizationOptions {
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
/** The organization token the operator issued. Sent as x-org-token. */
|
|
11
|
+
token: string;
|
|
12
|
+
fetch?: typeof fetch;
|
|
13
|
+
}
|
|
14
|
+
/** A project the organization just made, with its first key — shown here and never again. */
|
|
15
|
+
export interface CreatedProject {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
key: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class SimStreamOrganization {
|
|
21
|
+
private readonly base;
|
|
22
|
+
private readonly token;
|
|
23
|
+
private readonly fetchImpl;
|
|
24
|
+
constructor(opts: OrganizationOptions);
|
|
25
|
+
/**
|
|
26
|
+
* Makes a project and its first key (POST /api/projects, coordinator/dashboard.go). The key is stored hashed on the
|
|
27
|
+
* other side, so this answer is the only place it exists: keep it before dropping the response. A name is unique
|
|
28
|
+
* inside the organization; a second project under the same name is refused.
|
|
29
|
+
*/
|
|
30
|
+
createProject(name: string): Promise<CreatedProject>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* An organization's own hand: making the projects its keys belong to.
|
|
4
|
+
*
|
|
5
|
+
* Separate from the customer client for the reason the admin one is: a project's key can run simulators and upload
|
|
6
|
+
* builds for that project, and must never be able to make another project. The organization token can, and nothing
|
|
7
|
+
* but the service that owns the organization should hold it.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SimStreamOrganization = void 0;
|
|
11
|
+
class SimStreamOrganization {
|
|
12
|
+
base;
|
|
13
|
+
token;
|
|
14
|
+
fetchImpl;
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
if (!opts.baseUrl)
|
|
17
|
+
throw new Error('baseUrl is required');
|
|
18
|
+
if (!opts.token)
|
|
19
|
+
throw new Error('token is required');
|
|
20
|
+
this.base = opts.baseUrl.replace(/\/+$/, '');
|
|
21
|
+
this.token = opts.token;
|
|
22
|
+
this.fetchImpl = opts.fetch ?? globalThis.fetch;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Makes a project and its first key (POST /api/projects, coordinator/dashboard.go). The key is stored hashed on the
|
|
26
|
+
* other side, so this answer is the only place it exists: keep it before dropping the response. A name is unique
|
|
27
|
+
* inside the organization; a second project under the same name is refused.
|
|
28
|
+
*/
|
|
29
|
+
async createProject(name) {
|
|
30
|
+
const res = await this.fetchImpl(`${this.base}/api/projects`, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: { 'x-org-token': this.token, 'content-type': 'application/json' },
|
|
33
|
+
body: JSON.stringify({ name }),
|
|
34
|
+
});
|
|
35
|
+
if (!res.ok)
|
|
36
|
+
throw new Error(`simstream: the project could not be made (${res.status}): ${(await res.text().catch(() => '')).trim()}`);
|
|
37
|
+
const made = (await res.json());
|
|
38
|
+
if (!made.id || !made.key)
|
|
39
|
+
throw new Error('simstream: the coordinator made a project with no id or key');
|
|
40
|
+
return { id: made.id, name: made.name ?? name, key: made.key };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.SimStreamOrganization = SimStreamOrganization;
|