openvibers/openvibe.sdk Commits
SDK: the product at openre.stream is OpenRestream (owner, 2026-10-09) (#27)
Changes
@@@ -182,7 +182,7 @@ Until OpenVibe.Tools serves the gateway facade (Tools S6), point the jobs client| `openvibe-sdk/projects` | both (user token) | `createProjectsClient(client)`: `catalog`, `list`, `create`, `get`, `update`, `archive`, `setAllowance`, `setEnvironmentPolicy`, `members.*`, `apps.*`, `credentials.list/rotate/revoke`, `grants.list/request/approve/deny/revoke`, `quotas.*`, `audit`, `iterateAudit` || `openvibe-sdk/resources` | server | `parseResourceName`/`resourceName`/`resourceNameOf` (OVRN, via the pinned `contracts.resources`) and `RESOURCE_KINDS` (only the chosen `med`/`wch` prefixes); `createResourceIndex({authorities, token, fetch, pageLimit, concurrency, timeoutMs, maxPages, maxMs})`: `list({project, kind, limit})` -> `{resources, stale}`, fanning out over the authorities' `GET /api/v1/resources`, following each opaque `next_cursor` and merging `common.resource-list-result@1` pages (an authority that fails — or whose cursor chain repeats, outruns `maxPages`, or outruns `maxMs` — is reported in `stale`, never fatal), and `iterate`; `createResourceClient({origin, token})`: `control(request)` POSTs a `common.resource-control-request@1` to `/api/v1/resources/control` — idempotency-keyed, transient failures retried with the same key and body, a thrown error carrying that `idempotencyKey` — and returns the `common.resource-control-result@1` (`done`/`pending`/`refused`/`failed`, a refused/failed one returned even with a non-retryable non-2xx) || `openvibe-sdk/geo` | both | `createGeoClient(client, {samples?, timeoutMs?})`: `nodes({role, region})` from Network's public node registry, `measure(nodes)` (beacon round trips, fastest first), `nearest({role, region, preferRegion})` → `{node, rtt_ms, measured}` (up/degraded nodes only; falls back to preferRegion when nothing can be measured) |--| `openvibe-sdk/openre` | server | `createOpenReClient(client, {baseUrl?, publicUrl?})`: OpenRe.Stream, the streaming engine. `streams` (`byExternalRef`, `create`, `get`, `update`, `rotateKey`, `destinations`, `addDestination`), `destinations` (`test`, `start`, `stop`, `logs`), `sessions` (`get`, `playback` cached 10 s, `end`, `outputs`), `workers`, `manageUrl`; `{subject}` acts for a person (X-OV-Subject) |++| `openvibe-sdk/openre` | server | `createOpenReClient(client, {baseUrl?, publicUrl?})`: OpenRestream, the streaming engine. `streams` (`byExternalRef`, `create`, `get`, `update`, `rotateKey`, `destinations`, `addDestination`), `destinations` (`test`, `start`, `stop`, `logs`), `sessions` (`get`, `playback` cached 10 s, `end`, `outputs`), `workers`, `manageUrl`; `{subject}` acts for a person (X-OV-Subject) || `openvibe-sdk/vip` | server | `createVipClient({baseUrl?, tokenClient \| getToken, fetch?, timeoutMs?})`: `evaluate({subject, resource, owner, fallback, mode})`, `checkEntitlement({subject, creator, product, mode})`, `isMember(subject, creator)`; every failure is a denial. `createVipCache({vip, ttlMs, denyTtlMs, unavailableTtlMs})`: `entitlement`, `peekEntitlement`, `evaluate`, `invalidate`, `handleEvent` (`vip.membership.changed` and Billing's entitlement events drop a member's answers at once), `clear`, `bounds` || `openvibe-sdk/usage` | server | `usageSample(fields)` builds a `platform.usage-sample@1` record (required `id`, `idempotency_key`, `service`, `operation`, `quantity`, `unit`; `at` defaults to now ISO, `source` to `openvibe-sdk/usage`; null fields stripped; money fields never invented); `usageKey(service, ...parts)` joins an idempotency key with `:`; `validateUsageSample(record)` → `{ok, errors}` (openvibe-contracts, required lazily). `createUsageReporter({ db, service, source, table, billingUrl, tokenClient, audience, requireProject, ... })` owns one service's readings: `key(...parts)`/`sample(fields)`, and `record(t, reading)` queues the reading idempotency-keyed in the outbox inside the caller's transaction, relayed to Billing's `billing.usage.record` with backoff (a retry is never dropped; only Billing refusing the reading itself — any 4xx but 401/403/404/408/425/429, which stay pending — marks a row rejected; a 401 drops the cached token). The reporter bills whatever reading it is given: never record first-party or sandbox traffic (pass `requireProject: true` to refuse a reading without a `prj_…` project). `openvibe-sdk/govern` builds its `onUsage` record with it || `openvibe-sdk/commerce` | server | `createCommerceClient(config, {caps, fetchImpl?, tokenClients?, timeoutMs?})`: the Billing client Tips and VIP share. `config` = `{billing: {url, audience, timeoutMs = 10000}, network: {internalUrl}, oauth: {clientId, clientSecret}}`; `caps` maps `intent`, `transfer`, `subscription`, `entitlement` (and optional `rates`, default `entitlement`) to capability strings, one lazily created `serviceAuth` token client per distinct string (`scope` = the string) unless `tokenClients` supplies one, keyed by logical key or capability. Methods: `createIntent` (`kind` purchase with `bits`, or subscription with `creator`/`autoRenew`), `createTransfer`, `refundTransfer`, `subscribeWithCredit`, `cancelSubscription`, `getSubscription`, `listSubscriptions`, `entitlement`, `rates`, `baseUrl`. `Idempotency-Key` is sent verbatim; a 401 invalidates the token and retries once with the same key; problem+json becomes `CommerceError` (`status`, `code`, `body`, `retryable`). `intentKey(prefix, parts)` joins the parts that are set; `receipt(kind, fields)` → `{kind, at, ...fields}` (null stripped, never posted). `openvibe-contracts` is required lazily |@@@ -1850,7 +1850,7 @@ function createBotClient(client, defaults = {}) {*/command: (id, input, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/commands`, json: input }, o),streaming: {-- /** The owner's OpenRe toggles (Bot stores no copy). A member read. */++ /** The owner's OpenRestream toggles (Bot stores no copy). A member read. */get: (id, o = {}) => call({ path: `/api/v1/robots/${enc(id)}/streaming` }, o),/** { to?, on? } (a service must also act for the owner) -> the new streaming state. */set: (id, input = {}, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/streaming`, json: input }, o),@@@ -13,7 +13,7 @@ dependency, and a service that lacks the package gets an error naming it (`code:Convert one service at a time, smallest first (the audit's order): Blog, Codes, News, Deals, Coupons, VIP, Tips, Trade(errors only), Wiki, Reviews, Network, Community, Billing, Bot, Chat, Host, AI, Events, Search, Sources, Media,--OpenRe.Stream, Live.++OpenRestream, Live.## The stop@@@ -154,9 +154,9 @@ lifecycle = gracefulStop({with the `accepting` readiness check above replacing `_bootComplete = false`. The drill branch (3 s) stays outside thekit.--### OpenRe.Stream++### OpenRestream--It has no hard timer today. `gracefulStop({ name: 'OpenRe', server, close: [...] })` adds one (5 s, exit 1): new++It has no hard timer today. `gracefulStop({ name: 'OpenRestream', server, close: [...] })` adds one (5 s, exit 1): newbehaviour, but a safer one.## The telemetry@@@ -96,7 +96,7 @@ function createBotClient(client, defaults = {}) {*/command: (id, input, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/commands`, json: input }, o),streaming: {-- /** The owner's OpenRe toggles (Bot stores no copy). A member read. */++ /** The owner's OpenRestream toggles (Bot stores no copy). A member read. */get: (id, o = {}) => call({ path: `/api/v1/robots/${enc(id)}/streaming` }, o),/** { to?, on? } (a service must also act for the owner) -> the new streaming state. */set: (id, input = {}, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/streaming`, json: input }, o),@@@ -1,6 +1,6 @@'use strict';/**-- * openvibe-sdk/openre — OpenRe.Stream, the platform's streaming engine (ingest, sessions, restream outputs), for++ * openvibe-sdk/openre — OpenRestream, the platform's streaming engine (ingest, sessions, restream outputs), for* every product that puts a stream on air (OpenVibe.Live first). One client instead of a copy in each product.* Server-side: it sends a Network service token for audience openvibe.openre.*@@@ -13,7 +13,7 @@** Grants (on the caller's principal, audience openvibe.openre): openre.stream.read / .write, openre.key.rotate,* openre.output.read / .write, openre.session.read / .end. `subject` names the person a call acts for-- * (X-OV-Subject; a usr_ id); OpenRe checks that they own the stream. Errors are OpenVibeError (status, code);++ * (X-OV-Subject; a usr_ id); OpenRestream checks that they own the stream. Errors are OpenVibeError (status, code);* a missing stream, destination or session is null from get(), not an error.* Shapes: Contracts openre.stream@1, openre.destination@1, openre.output@1, openre.session-read-result@1.*/@@@ -82,7 +82,7 @@ function createOpenReClient(client, { baseUrl, publicUrl = 'https://openre.streasessions,outputLogs: (id, { subject, limit } = {}) => call({ path: `/api/v1/outputs/${enc(id)}/logs`, query: { limit }, subject }),workers: () => call({ path: '/api/v1/workers' }),-- /** The standalone UI's page for a stream (for "manage on OpenRe.Stream" links). */++ /** The standalone UI's page for a stream (for "manage on OpenRestream" links). */manageUrl: (streamId) => `${String(publicUrl).replace(/\/+$/, '')}/streams/${enc(streamId || '')}`,clearCache: () => playbackCache.clear(),};@@@ -1,5 +1,5 @@'use strict';--/** OpenRe: service-token calls with the acting subject, external_ref lookup, key rotation, null for a missing++/** OpenRestream: service-token calls with the acting subject, external_ref lookup, key rotation, null for a missing* stream or session, playback cached 10 s, destinations and sessions paths, and errors kept as OpenVibeError. */const assert = require('node:assert/strict');const { stubServer, send, run } = require('./helpers');
@@ -182,7 +182,7 @@ Until OpenVibe.Tools serves the gateway facade (Tools S6), point the jobs client
@@ -182,7 +182,7 @@ Until OpenVibe.Tools serves the gateway facade (Tools S6), point the jobs client
| `openvibe-sdk/projects` | both (user token) | `createProjectsClient(client)`: `catalog`, `list`, `create`, `get`, `update`, `archive`, `setAllowance`, `setEnvironmentPolicy`, `members.*`, `apps.*`, `credentials.list/rotate/revoke`, `grants.list/request/approve/deny/revoke`, `quotas.*`, `audit`, `iterateAudit` |
| `openvibe-sdk/projects` | both (user token) | `createProjectsClient(client)`: `catalog`, `list`, `create`, `get`, `update`, `archive`, `setAllowance`, `setEnvironmentPolicy`, `members.*`, `apps.*`, `credentials.list/rotate/revoke`, `grants.list/request/approve/deny/revoke`, `quotas.*`, `audit`, `iterateAudit` |
| `openvibe-sdk/resources` | server | `parseResourceName`/`resourceName`/`resourceNameOf` (OVRN, via the pinned `contracts.resources`) and `RESOURCE_KINDS` (only the chosen `med`/`wch` prefixes); `createResourceIndex({authorities, token, fetch, pageLimit, concurrency, timeoutMs, maxPages, maxMs})`: `list({project, kind, limit})` -> `{resources, stale}`, fanning out over the authorities' `GET /api/v1/resources`, following each opaque `next_cursor` and merging `common.resource-list-result@1` pages (an authority that fails — or whose cursor chain repeats, outruns `maxPages`, or outruns `maxMs` — is reported in `stale`, never fatal), and `iterate`; `createResourceClient({origin, token})`: `control(request)` POSTs a `common.resource-control-request@1` to `/api/v1/resources/control` — idempotency-keyed, transient failures retried with the same key and body, a thrown error carrying that `idempotencyKey` — and returns the `common.resource-control-result@1` (`done`/`pending`/`refused`/`failed`, a refused/failed one returned even with a non-retryable non-2xx) |
| `openvibe-sdk/resources` | server | `parseResourceName`/`resourceName`/`resourceNameOf` (OVRN, via the pinned `contracts.resources`) and `RESOURCE_KINDS` (only the chosen `med`/`wch` prefixes); `createResourceIndex({authorities, token, fetch, pageLimit, concurrency, timeoutMs, maxPages, maxMs})`: `list({project, kind, limit})` -> `{resources, stale}`, fanning out over the authorities' `GET /api/v1/resources`, following each opaque `next_cursor` and merging `common.resource-list-result@1` pages (an authority that fails — or whose cursor chain repeats, outruns `maxPages`, or outruns `maxMs` — is reported in `stale`, never fatal), and `iterate`; `createResourceClient({origin, token})`: `control(request)` POSTs a `common.resource-control-request@1` to `/api/v1/resources/control` — idempotency-keyed, transient failures retried with the same key and body, a thrown error carrying that `idempotencyKey` — and returns the `common.resource-control-result@1` (`done`/`pending`/`refused`/`failed`, a refused/failed one returned even with a non-retryable non-2xx) |
| `openvibe-sdk/geo` | both | `createGeoClient(client, {samples?, timeoutMs?})`: `nodes({role, region})` from Network's public node registry, `measure(nodes)` (beacon round trips, fastest first), `nearest({role, region, preferRegion})` → `{node, rtt_ms, measured}` (up/degraded nodes only; falls back to preferRegion when nothing can be measured) |
| `openvibe-sdk/geo` | both | `createGeoClient(client, {samples?, timeoutMs?})`: `nodes({role, region})` from Network's public node registry, `measure(nodes)` (beacon round trips, fastest first), `nearest({role, region, preferRegion})` → `{node, rtt_ms, measured}` (up/degraded nodes only; falls back to preferRegion when nothing can be measured) |
-| `openvibe-sdk/openre` | server | `createOpenReClient(client, {baseUrl?, publicUrl?})`: OpenRe.Stream, the streaming engine. `streams` (`byExternalRef`, `create`, `get`, `update`, `rotateKey`, `destinations`, `addDestination`), `destinations` (`test`, `start`, `stop`, `logs`), `sessions` (`get`, `playback` cached 10 s, `end`, `outputs`), `workers`, `manageUrl`; `{subject}` acts for a person (X-OV-Subject) |
+| `openvibe-sdk/openre` | server | `createOpenReClient(client, {baseUrl?, publicUrl?})`: OpenRestream, the streaming engine. `streams` (`byExternalRef`, `create`, `get`, `update`, `rotateKey`, `destinations`, `addDestination`), `destinations` (`test`, `start`, `stop`, `logs`), `sessions` (`get`, `playback` cached 10 s, `end`, `outputs`), `workers`, `manageUrl`; `{subject}` acts for a person (X-OV-Subject) |
| `openvibe-sdk/vip` | server | `createVipClient({baseUrl?, tokenClient \| getToken, fetch?, timeoutMs?})`: `evaluate({subject, resource, owner, fallback, mode})`, `checkEntitlement({subject, creator, product, mode})`, `isMember(subject, creator)`; every failure is a denial. `createVipCache({vip, ttlMs, denyTtlMs, unavailableTtlMs})`: `entitlement`, `peekEntitlement`, `evaluate`, `invalidate`, `handleEvent` (`vip.membership.changed` and Billing's entitlement events drop a member's answers at once), `clear`, `bounds` |
| `openvibe-sdk/vip` | server | `createVipClient({baseUrl?, tokenClient \| getToken, fetch?, timeoutMs?})`: `evaluate({subject, resource, owner, fallback, mode})`, `checkEntitlement({subject, creator, product, mode})`, `isMember(subject, creator)`; every failure is a denial. `createVipCache({vip, ttlMs, denyTtlMs, unavailableTtlMs})`: `entitlement`, `peekEntitlement`, `evaluate`, `invalidate`, `handleEvent` (`vip.membership.changed` and Billing's entitlement events drop a member's answers at once), `clear`, `bounds` |
| `openvibe-sdk/usage` | server | `usageSample(fields)` builds a `platform.usage-sample@1` record (required `id`, `idempotency_key`, `service`, `operation`, `quantity`, `unit`; `at` defaults to now ISO, `source` to `openvibe-sdk/usage`; null fields stripped; money fields never invented); `usageKey(service, ...parts)` joins an idempotency key with `:`; `validateUsageSample(record)` → `{ok, errors}` (openvibe-contracts, required lazily). `createUsageReporter({ db, service, source, table, billingUrl, tokenClient, audience, requireProject, ... })` owns one service's readings: `key(...parts)`/`sample(fields)`, and `record(t, reading)` queues the reading idempotency-keyed in the outbox inside the caller's transaction, relayed to Billing's `billing.usage.record` with backoff (a retry is never dropped; only Billing refusing the reading itself — any 4xx but 401/403/404/408/425/429, which stay pending — marks a row rejected; a 401 drops the cached token). The reporter bills whatever reading it is given: never record first-party or sandbox traffic (pass `requireProject: true` to refuse a reading without a `prj_…` project). `openvibe-sdk/govern` builds its `onUsage` record with it |
| `openvibe-sdk/usage` | server | `usageSample(fields)` builds a `platform.usage-sample@1` record (required `id`, `idempotency_key`, `service`, `operation`, `quantity`, `unit`; `at` defaults to now ISO, `source` to `openvibe-sdk/usage`; null fields stripped; money fields never invented); `usageKey(service, ...parts)` joins an idempotency key with `:`; `validateUsageSample(record)` → `{ok, errors}` (openvibe-contracts, required lazily). `createUsageReporter({ db, service, source, table, billingUrl, tokenClient, audience, requireProject, ... })` owns one service's readings: `key(...parts)`/`sample(fields)`, and `record(t, reading)` queues the reading idempotency-keyed in the outbox inside the caller's transaction, relayed to Billing's `billing.usage.record` with backoff (a retry is never dropped; only Billing refusing the reading itself — any 4xx but 401/403/404/408/425/429, which stay pending — marks a row rejected; a 401 drops the cached token). The reporter bills whatever reading it is given: never record first-party or sandbox traffic (pass `requireProject: true` to refuse a reading without a `prj_…` project). `openvibe-sdk/govern` builds its `onUsage` record with it |
| `openvibe-sdk/commerce` | server | `createCommerceClient(config, {caps, fetchImpl?, tokenClients?, timeoutMs?})`: the Billing client Tips and VIP share. `config` = `{billing: {url, audience, timeoutMs = 10000}, network: {internalUrl}, oauth: {clientId, clientSecret}}`; `caps` maps `intent`, `transfer`, `subscription`, `entitlement` (and optional `rates`, default `entitlement`) to capability strings, one lazily created `serviceAuth` token client per distinct string (`scope` = the string) unless `tokenClients` supplies one, keyed by logical key or capability. Methods: `createIntent` (`kind` purchase with `bits`, or subscription with `creator`/`autoRenew`), `createTransfer`, `refundTransfer`, `subscribeWithCredit`, `cancelSubscription`, `getSubscription`, `listSubscriptions`, `entitlement`, `rates`, `baseUrl`. `Idempotency-Key` is sent verbatim; a 401 invalidates the token and retries once with the same key; problem+json becomes `CommerceError` (`status`, `code`, `body`, `retryable`). `intentKey(prefix, parts)` joins the parts that are set; `receipt(kind, fields)` → `{kind, at, ...fields}` (null stripped, never posted). `openvibe-contracts` is required lazily |
| `openvibe-sdk/commerce` | server | `createCommerceClient(config, {caps, fetchImpl?, tokenClients?, timeoutMs?})`: the Billing client Tips and VIP share. `config` = `{billing: {url, audience, timeoutMs = 10000}, network: {internalUrl}, oauth: {clientId, clientSecret}}`; `caps` maps `intent`, `transfer`, `subscription`, `entitlement` (and optional `rates`, default `entitlement`) to capability strings, one lazily created `serviceAuth` token client per distinct string (`scope` = the string) unless `tokenClients` supplies one, keyed by logical key or capability. Methods: `createIntent` (`kind` purchase with `bits`, or subscription with `creator`/`autoRenew`), `createTransfer`, `refundTransfer`, `subscribeWithCredit`, `cancelSubscription`, `getSubscription`, `listSubscriptions`, `entitlement`, `rates`, `baseUrl`. `Idempotency-Key` is sent verbatim; a 401 invalidates the token and retries once with the same key; problem+json becomes `CommerceError` (`status`, `code`, `body`, `retryable`). `intentKey(prefix, parts)` joins the parts that are set; `receipt(kind, fields)` → `{kind, at, ...fields}` (null stripped, never posted). `openvibe-contracts` is required lazily |
@@ -1850,7 +1850,7 @@ function createBotClient(client, defaults = {}) {
@@ -1850,7 +1850,7 @@ function createBotClient(client, defaults = {}) {
*/
*/
command: (id, input, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/commands`, json: input }, o),
command: (id, input, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/commands`, json: input }, o),
streaming: {
streaming: {
- /** The owner's OpenRe toggles (Bot stores no copy). A member read. */
+ /** The owner's OpenRestream toggles (Bot stores no copy). A member read. */
get: (id, o = {}) => call({ path: `/api/v1/robots/${enc(id)}/streaming` }, o),
get: (id, o = {}) => call({ path: `/api/v1/robots/${enc(id)}/streaming` }, o),
/** { to?, on? } (a service must also act for the owner) -> the new streaming state. */
/** { to?, on? } (a service must also act for the owner) -> the new streaming state. */
set: (id, input = {}, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/streaming`, json: input }, o),
set: (id, input = {}, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/streaming`, json: input }, o),
@@ -13,7 +13,7 @@ dependency, and a service that lacks the package gets an error naming it (`code:
@@ -13,7 +13,7 @@ dependency, and a service that lacks the package gets an error naming it (`code:
Convert one service at a time, smallest first (the audit's order): Blog, Codes, News, Deals, Coupons, VIP, Tips, Trade
Convert one service at a time, smallest first (the audit's order): Blog, Codes, News, Deals, Coupons, VIP, Tips, Trade
(errors only), Wiki, Reviews, Network, Community, Billing, Bot, Chat, Host, AI, Events, Search, Sources, Media,
(errors only), Wiki, Reviews, Network, Community, Billing, Bot, Chat, Host, AI, Events, Search, Sources, Media,
-OpenRe.Stream, Live.
+OpenRestream, Live.
## The stop
## The stop
@@ -154,9 +154,9 @@ lifecycle = gracefulStop({
@@ -154,9 +154,9 @@ lifecycle = gracefulStop({
with the `accepting` readiness check above replacing `_bootComplete = false`. The drill branch (3 s) stays outside the
with the `accepting` readiness check above replacing `_bootComplete = false`. The drill branch (3 s) stays outside the
kit.
kit.
-### OpenRe.Stream
+### OpenRestream
-It has no hard timer today. `gracefulStop({ name: 'OpenRe', server, close: [...] })` adds one (5 s, exit 1): new
+It has no hard timer today. `gracefulStop({ name: 'OpenRestream', server, close: [...] })` adds one (5 s, exit 1): new
behaviour, but a safer one.
behaviour, but a safer one.
## The telemetry
## The telemetry
@@ -96,7 +96,7 @@ function createBotClient(client, defaults = {}) {
@@ -96,7 +96,7 @@ function createBotClient(client, defaults = {}) {
*/
*/
command: (id, input, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/commands`, json: input }, o),
command: (id, input, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/commands`, json: input }, o),
streaming: {
streaming: {
- /** The owner's OpenRe toggles (Bot stores no copy). A member read. */
+ /** The owner's OpenRestream toggles (Bot stores no copy). A member read. */
get: (id, o = {}) => call({ path: `/api/v1/robots/${enc(id)}/streaming` }, o),
get: (id, o = {}) => call({ path: `/api/v1/robots/${enc(id)}/streaming` }, o),
/** { to?, on? } (a service must also act for the owner) -> the new streaming state. */
/** { to?, on? } (a service must also act for the owner) -> the new streaming state. */
set: (id, input = {}, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/streaming`, json: input }, o),
set: (id, input = {}, o = {}) => call({ method: 'POST', path: `/api/v1/robots/${enc(id)}/streaming`, json: input }, o),
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
'use strict';
'use strict';
/**
/**
- * openvibe-sdk/openre — OpenRe.Stream, the platform's streaming engine (ingest, sessions, restream outputs), for
+ * openvibe-sdk/openre — OpenRestream, the platform's streaming engine (ingest, sessions, restream outputs), for
* every product that puts a stream on air (OpenVibe.Live first). One client instead of a copy in each product.
* every product that puts a stream on air (OpenVibe.Live first). One client instead of a copy in each product.
* Server-side: it sends a Network service token for audience openvibe.openre.
* Server-side: it sends a Network service token for audience openvibe.openre.
*
*
@@ -13,7 +13,7 @@
@@ -13,7 +13,7 @@
*
*
* Grants (on the caller's principal, audience openvibe.openre): openre.stream.read / .write, openre.key.rotate,
* Grants (on the caller's principal, audience openvibe.openre): openre.stream.read / .write, openre.key.rotate,
* openre.output.read / .write, openre.session.read / .end. `subject` names the person a call acts for
* openre.output.read / .write, openre.session.read / .end. `subject` names the person a call acts for
- * (X-OV-Subject; a usr_ id); OpenRe checks that they own the stream. Errors are OpenVibeError (status, code);
+ * (X-OV-Subject; a usr_ id); OpenRestream checks that they own the stream. Errors are OpenVibeError (status, code);
* a missing stream, destination or session is null from get(), not an error.
* a missing stream, destination or session is null from get(), not an error.
* Shapes: Contracts openre.stream@1, openre.destination@1, openre.output@1, openre.session-read-result@1.
* Shapes: Contracts openre.stream@1, openre.destination@1, openre.output@1, openre.session-read-result@1.
*/
*/
@@ -82,7 +82,7 @@ function createOpenReClient(client, { baseUrl, publicUrl = 'https://openre.strea
@@ -82,7 +82,7 @@ function createOpenReClient(client, { baseUrl, publicUrl = 'https://openre.strea
sessions,
sessions,
outputLogs: (id, { subject, limit } = {}) => call({ path: `/api/v1/outputs/${enc(id)}/logs`, query: { limit }, subject }),
outputLogs: (id, { subject, limit } = {}) => call({ path: `/api/v1/outputs/${enc(id)}/logs`, query: { limit }, subject }),
workers: () => call({ path: '/api/v1/workers' }),
workers: () => call({ path: '/api/v1/workers' }),
- /** The standalone UI's page for a stream (for "manage on OpenRe.Stream" links). */
+ /** The standalone UI's page for a stream (for "manage on OpenRestream" links). */
manageUrl: (streamId) => `${String(publicUrl).replace(/\/+$/, '')}/streams/${enc(streamId || '')}`,
manageUrl: (streamId) => `${String(publicUrl).replace(/\/+$/, '')}/streams/${enc(streamId || '')}`,
clearCache: () => playbackCache.clear(),
clearCache: () => playbackCache.clear(),
};
};
@@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
'use strict';
'use strict';
-/** OpenRe: service-token calls with the acting subject, external_ref lookup, key rotation, null for a missing
+/** OpenRestream: service-token calls with the acting subject, external_ref lookup, key rotation, null for a missing
* stream or session, playback cached 10 s, destinations and sessions paths, and errors kept as OpenVibeError. */
* stream or session, playback cached 10 s, destinations and sessions paths, and errors kept as OpenVibeError. */
const assert = require('node:assert/strict');
const assert = require('node:assert/strict');
const { stubServer, send, run } = require('./helpers');
const { stubServer, send, run } = require('./helpers');