osra 0.6.8 → 0.6.10

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.
@@ -2,6 +2,8 @@ import type { Capable } from '../types.js';
2
2
  import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js';
3
3
  import type { BoxedMessagePort } from './message-port.js';
4
4
  export declare const type: 'abortSignal';
5
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
6
+ export declare const objectsOnly = true;
5
7
  type AbortMessage = {
6
8
  type: 'abort';
7
9
  reason?: Capable;
@@ -1,5 +1,7 @@
1
1
  import type { RevivableContext } from './utils.js';
2
2
  export declare const type: 'arrayBuffer';
3
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
4
+ export declare const objectsOnly = true;
3
5
  export declare const isType: (value: unknown) => value is ArrayBuffer;
4
6
  export declare const box: <T extends ArrayBuffer, T2 extends RevivableContext>(value: T, context: T2) => {
5
7
  __OSRA_BOX__: 'revivable';
@@ -2,6 +2,8 @@ import type { Capable } from '../types.js';
2
2
  import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js';
3
3
  import { BoxedFunction } from './function.js';
4
4
  export declare const type: 'asyncIterator';
5
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
6
+ export declare const objectsOnly = true;
5
7
  type AnyAsyncIterable = {
6
8
  [Symbol.asyncIterator]: () => AsyncIterator<unknown>;
7
9
  };
@@ -1,5 +1,7 @@
1
1
  import type { RevivableContext } from './utils.js';
2
2
  export declare const type: 'date';
3
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
4
+ export declare const objectsOnly = true;
3
5
  export declare const isType: (value: unknown) => value is Date;
4
6
  export declare const box: <T extends Date, T2 extends RevivableContext>(value: T, _context: T2) => {
5
7
  __OSRA_BOX__: 'revivable';
@@ -1,6 +1,8 @@
1
1
  import type { Capable } from '../types.js';
2
2
  import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js';
3
3
  export declare const type: 'error';
4
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
5
+ export declare const objectsOnly = true;
4
6
  export type BoxedError = BoxBaseType<typeof type> & {
5
7
  name: string;
6
8
  message: string;
@@ -1,5 +1,7 @@
1
1
  import { type RevivableContext } from './utils.js';
2
2
  export declare const type: 'eventTarget';
3
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
4
+ export declare const objectsOnly = true;
3
5
  type ListenerOpts = boolean | {
4
6
  capture?: boolean;
5
7
  once?: boolean;
@@ -1,6 +1,8 @@
1
1
  import type { Capable } from '../types.js';
2
2
  import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js';
3
3
  export declare const type: 'event';
4
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
5
+ export declare const objectsOnly = true;
4
6
  /** Boxes Event/CustomEvent only. Subclass-specific fields (MessageEvent.data,
5
7
  * ErrorEvent.error, ProgressEvent.loaded, etc.) are dropped on the wire. */
6
8
  export type BoxedEvent = BoxBaseType<typeof type> & {
@@ -95,6 +95,7 @@ declare const isClonable: (value: unknown) => value is Clonable;
95
95
  export declare const clonable: {
96
96
  readonly type: 'clonable';
97
97
  readonly capableOnly: true;
98
+ readonly objectsOnly: true;
98
99
  readonly isType: typeof isClonable;
99
100
  readonly box: (value: Clonable, _context: RevivableContext<any>) => Clonable;
100
101
  readonly revive: (value: BoxedClonable, _context: RevivableContext<any>) => Clonable;
@@ -124,6 +125,7 @@ declare const isTransferable: (value: unknown) => value is Transferable;
124
125
  export declare const transferable: {
125
126
  readonly type: 'transferable';
126
127
  readonly capableOnly: true;
128
+ readonly objectsOnly: true;
127
129
  readonly isType: typeof isTransferable;
128
130
  readonly box: (value: Transferable, _context: RevivableContext<any>) => Transferable;
129
131
  readonly revive: (value: BoxedTransferable, _context: RevivableContext<any>) => Transferable;
@@ -133,6 +135,7 @@ declare const isBlob: (value: unknown) => value is Blob;
133
135
  export declare const blob: {
134
136
  readonly type: 'blob';
135
137
  readonly capableOnly: true;
138
+ readonly objectsOnly: true;
136
139
  readonly isType: typeof isBlob;
137
140
  readonly box: (value: Blob, context: RevivableContext<any>) => Blob;
138
141
  readonly revive: (value: BoxedBlob, _context: RevivableContext<any>) => Blob;
@@ -140,6 +143,7 @@ export declare const blob: {
140
143
  export type BoxedUnclonable = BoxBaseType<'unclonable'>;
141
144
  export declare const unclonable: {
142
145
  readonly type: 'unclonable';
146
+ readonly objectsOnly: true;
143
147
  readonly isType: (value: unknown) => value is never;
144
148
  readonly box: (_value: never, _context: RevivableContext<any>) => BoxedUnclonable;
145
149
  readonly revive: (_value: BoxedUnclonable, _context: RevivableContext<any>) => Record<string, never>;
@@ -3,6 +3,8 @@ import type { UnderlyingType, RevivableContext, BoxBase as BoxBaseType } from '.
3
3
  import { type EventPort } from '../utils/event-channel.js';
4
4
  import { BoxedMessagePort } from './message-port.js';
5
5
  export declare const type: 'function';
6
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
7
+ export declare const objectsOnly = true;
6
8
  type CallContext = [EventPort<Capable>, Capable[]];
7
9
  export type BoxedFunction<T extends (...args: any[]) => any = (...args: any[]) => any> = BoxBaseType<typeof type> & {
8
10
  port: BoxedMessagePort<CallContext>;
@@ -1,5 +1,7 @@
1
1
  import type { RevivableContext } from './utils.js';
2
2
  export declare const type: 'headers';
3
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
4
+ export declare const objectsOnly = true;
3
5
  export declare const isType: (value: unknown) => value is Headers;
4
6
  export declare const box: <T extends Headers, T2 extends RevivableContext>(value: T, _context: T2) => {
5
7
  __OSRA_BOX__: 'revivable';
@@ -2,6 +2,8 @@ import type { Capable, Uuid } from '../types.js';
2
2
  import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js';
3
3
  import type { UnderlyingType } from '../utils/type.js';
4
4
  export declare const type: 'identity';
5
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
6
+ export declare const objectsOnly = true;
5
7
  export type Messages = {
6
8
  type: 'identity-dispose';
7
9
  remoteUuid: Uuid;
@@ -29,6 +29,12 @@ export * from './utils.js';
29
29
  export type RevivableModule<T extends string = string, T2 = any, T3 extends BoxBase<T> = any, T4 extends MessageFields = MessageFields> = {
30
30
  readonly type: T;
31
31
  readonly isType: (value: unknown) => value is T2;
32
+ /** Declare `true` when `isType` never claims a primitive (string, number, boolean, bigint, symbol,
33
+ * undefined, null). The walker then skips the module for primitive leaves, which is most of what a
34
+ * large payload is made of. Leaving it off is always safe: the default is to call `isType` for
35
+ * every value, exactly as before. `objectsOnlyFlagsAreHonest` in the suite calls every flagged
36
+ * module with a set of primitives and fails if one of them says yes. */
37
+ readonly objectsOnly?: boolean;
32
38
  readonly box: ((value: T2, context: RevivableContext<any>) => T3) | ((...args: any[]) => any);
33
39
  readonly revive: (value: T3, context: RevivableContext<any>) => T2;
34
40
  readonly init?: (context: RevivableContext<any>) => void;
@@ -47,23 +53,27 @@ export declare const defaultRevivableModules: readonly [typeof transfer, typeof
47
53
  }, {
48
54
  readonly type: 'clonable';
49
55
  readonly capableOnly: true;
56
+ readonly objectsOnly: true;
50
57
  readonly isType: (value: unknown) => value is import("./fallbacks.js").Clonable;
51
58
  readonly box: (value: import("./fallbacks.js").Clonable, _context: RevivableContext<any>) => import("./fallbacks.js").Clonable;
52
59
  readonly revive: (value: import("./fallbacks.js").BoxedClonable, _context: RevivableContext<any>) => import("./fallbacks.js").Clonable;
53
60
  }, {
54
61
  readonly type: 'transferable';
55
62
  readonly capableOnly: true;
63
+ readonly objectsOnly: true;
56
64
  readonly isType: (value: unknown) => value is import("./fallbacks.js").Transferable;
57
65
  readonly box: (value: import("./fallbacks.js").Transferable, _context: RevivableContext<any>) => import("./fallbacks.js").Transferable;
58
66
  readonly revive: (value: import("./fallbacks.js").BoxedTransferable, _context: RevivableContext<any>) => import("./fallbacks.js").Transferable;
59
67
  }, {
60
68
  readonly type: 'blob';
61
69
  readonly capableOnly: true;
70
+ readonly objectsOnly: true;
62
71
  readonly isType: (value: unknown) => value is Blob;
63
72
  readonly box: (value: Blob, context: RevivableContext<any>) => Blob;
64
73
  readonly revive: (value: import("./fallbacks.js").BoxedBlob, _context: RevivableContext<any>) => Blob;
65
74
  }, typeof eventTarget, {
66
75
  readonly type: 'unclonable';
76
+ readonly objectsOnly: true;
67
77
  readonly isType: (value: unknown) => value is never;
68
78
  readonly box: (_value: never, _context: RevivableContext<any>) => import("./fallbacks.js").BoxedUnclonable;
69
79
  readonly revive: (_value: import("./fallbacks.js").BoxedUnclonable, _context: RevivableContext<any>) => Record<string, never>;
@@ -1,6 +1,8 @@
1
1
  import type { Capable } from '../types.js';
2
2
  import type { RevivableContext, UnderlyingType, BoxBase as BoxBaseType } from './utils.js';
3
3
  export declare const type: 'map';
4
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
5
+ export declare const objectsOnly = true;
4
6
  export type BoxedMap<T extends Map<Capable, Capable> = Map<Capable, Capable>> = BoxBaseType<typeof type> & {
5
7
  entries: Array<[Capable, Capable]>;
6
8
  } & {
@@ -5,6 +5,8 @@ import type { UnderlyingType } from '../utils/type.js';
5
5
  import type { BadFieldValue, BadFieldPath, BadFieldParent, ErrorMessage, BadValue, Path, ParentObject } from '../utils/capable-check.js';
6
6
  import { EventPort } from '../utils/event-channel.js';
7
7
  export declare const type: 'messagePort';
8
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
9
+ export declare const objectsOnly = true;
8
10
  export type Messages = {
9
11
  type: 'message';
10
12
  remoteUuid: Uuid;
@@ -39,6 +41,8 @@ type StructurableTransferablePort<T> = [T] extends [Capable] ? AnyPort<T> : AnyP
39
41
  };
40
42
  export declare const init: (context: RevivableContext) => void;
41
43
  export declare const isType: (value: unknown) => value is MessagePort | EventPort<StructurableTransferable>;
44
+ /** Post a payload that is already boxed. Anything else must go through `postMessage` as usual. */
45
+ export declare const postPreBoxed: (port: MessagePort, boxed: Capable, transferables?: Transferable[]) => void;
42
46
  export declare const box: <T, T2 extends RevivableContext = RevivableContext>(value: StructurableTransferablePort<T>, context: T2, options?: {
43
47
  autoBox?: boolean;
44
48
  }) => BoxedMessagePort<T>;
@@ -4,6 +4,8 @@ import type { UnderlyingType } from './index.js';
4
4
  import type { BadFieldValue, BadFieldPath, BadFieldParent, ErrorMessage, BadValue, Path, ParentObject } from '../utils/capable-check.js';
5
5
  import { BoxedMessagePort } from './message-port.js';
6
6
  export declare const type: 'promise';
7
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
8
+ export declare const objectsOnly = true;
7
9
  export type Context = {
8
10
  type: 'resolve';
9
11
  data: Capable;
@@ -3,6 +3,8 @@ import type { RevivableContext, BoxBase as BoxBaseType } from './utils.js';
3
3
  import type { UnderlyingType } from './index.js';
4
4
  import { BoxedMessagePort } from './message-port.js';
5
5
  export declare const type: 'readableStream';
6
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
7
+ export declare const objectsOnly = true;
6
8
  export type PullContext = {
7
9
  type: 'pull';
8
10
  } | {
@@ -1,5 +1,7 @@
1
1
  import type { RevivableContext } from './utils.js';
2
2
  export declare const type: 'request';
3
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
4
+ export declare const objectsOnly = true;
3
5
  export declare const isType: (value: unknown) => value is Request;
4
6
  export declare const box: <T extends Request, T2 extends RevivableContext>(value: T, context: T2) => {
5
7
  __OSRA_BOX__: 'revivable';
@@ -1,5 +1,7 @@
1
1
  import type { RevivableContext } from './utils.js';
2
2
  export declare const type: 'response';
3
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
4
+ export declare const objectsOnly = true;
3
5
  export declare const isType: (value: unknown) => value is Response;
4
6
  export declare const box: <T extends Response, T2 extends RevivableContext>(value: T, context: T2) => {
5
7
  __OSRA_BOX__: 'revivable';
@@ -1,6 +1,8 @@
1
1
  import type { Capable } from '../types.js';
2
2
  import type { RevivableContext, UnderlyingType, BoxBase as BoxBaseType } from './utils.js';
3
3
  export declare const type: 'set';
4
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
5
+ export declare const objectsOnly = true;
4
6
  export type BoxedSet<T extends Set<Capable> = Set<Capable>> = BoxBaseType<typeof type> & {
5
7
  values: Array<Capable>;
6
8
  } & {
@@ -1,6 +1,8 @@
1
1
  import type { Capable } from '../types.js';
2
2
  import type { BoxBase as BoxBaseType, RevivableContext, UnderlyingType } from './utils.js';
3
3
  export declare const type: 'transfer';
4
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
5
+ export declare const objectsOnly = true;
4
6
  declare const TRANSFER_MARKER: unique symbol;
5
7
  type TransferWrapper<T = unknown> = {
6
8
  readonly [TRANSFER_MARKER]: true;
@@ -3,6 +3,8 @@ import type { TypedArray, TypedArrayType } from '../utils/type-guards.js';
3
3
  import { BoxBase } from './utils.js';
4
4
  import { isTypedArray } from '../utils/type-guards.js';
5
5
  export declare const type: 'typedArray';
6
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
7
+ export declare const objectsOnly = true;
6
8
  type BoxedTypedArray<T extends TypedArray, T2 extends RevivableContext> = typeof BoxBase & {
7
9
  type: typeof type;
8
10
  } & {
@@ -3,6 +3,8 @@ import type { UnderlyingType } from './index.js';
3
3
  import type { Capable } from '../types.js';
4
4
  import { BoxedMessagePort } from './message-port.js';
5
5
  export declare const type: 'writableStream';
6
+ /** Never claims a primitive, so the walker can skip this module for primitive leaves. */
7
+ export declare const objectsOnly = true;
6
8
  export type WriteContext = {
7
9
  type: 'write';
8
10
  chunk: Capable;
package/build/types.d.ts CHANGED
@@ -32,7 +32,7 @@ export type Capable<TModules extends readonly RevivableModule[] = DefaultRevivab
32
32
  /** What a value looks like from the far side of the connection: functions
33
33
  * become async (calls cross the wire), containers map recursively,
34
34
  * everything else revives as itself. */
35
- export type Remote<T> = T extends (...args: infer P) => infer R ? (...args: P) => Promise<Remote<Awaited<R>>> : T extends Promise<infer U> ? Promise<Remote<U>> : T extends Map<any, any> | Set<any> | Date | Error | RegExp | ArrayBuffer | ArrayBufferView | Blob | File | FileList | ReadableStream | WritableStream | MessagePort | EventTarget | Request | Response | Headers ? T : T extends AsyncIterable<infer U> ? AsyncIterableIterator<Remote<U>> : T extends ReadonlyArray<unknown> ? {
35
+ export type Remote<T> = T extends (...args: infer P) => infer R ? (...args: P) => Promise<Remote<Awaited<R>>> : T extends Promise<infer U> ? Promise<Remote<U>> : T extends Map<infer K, infer V> ? Map<Remote<K>, Remote<V>> : T extends Set<infer V> ? Set<Remote<V>> : T extends ReadableStream<infer C> ? ReadableStream<Remote<C>> : T extends Date | Error | RegExp | ArrayBuffer | ArrayBufferView | Blob | File | FileList | WritableStream | MessagePort | AbortSignal | Request | Response | Headers ? T : T extends EventTarget ? EventTarget : T extends AsyncIterable<infer U> ? AsyncIterableIterator<Remote<U>> : T extends ReadonlyArray<unknown> ? {
36
36
  [K in keyof T]: Remote<T[K]>;
37
37
  } : T extends object ? {
38
38
  [K in keyof T]: Remote<T[K]>;
@@ -8,4 +8,4 @@ export * from './event-channel.js';
8
8
  export * from './type.js';
9
9
  export * from './capable-check.js';
10
10
  export * from './gc-tracker.js';
11
- export * from './teardown.js';
11
+ export { onTeardown, isTornDown } from './teardown.js';
@@ -1,6 +1,16 @@
1
1
  import type { Message } from '../types.js';
2
2
  import type { CustomEmitTransport, CustomReceiveTransport, CustomTransport, EmitJsonPlatformTransport, EmitTransport, JsonPlatformTransport, ReceiveJsonPlatformTransport, ReceiveTransport, Transport } from './transport.js';
3
3
  import type { WebExtOnConnect, WebExtOnMessage, WebExtPort, WebExtRuntime } from './webext-types.js';
4
+ /** Structural on purpose, never `typeof Float16Array`. That global type exists only in TypeScript's
5
+ * esnext lib, and naming it here lands it in the SHIPPED declarations, where a consumer on an older
6
+ * lib gets `Cannot find name 'Float16ArrayConstructor'` inside osra's own .d.ts, and every check
7
+ * built on the collapsed types degrades with it. Same shape of break as the webextension-polyfill
8
+ * import 0.6.6 and 0.6.7 shipped; `npm run check-consumer-types-legacy-lib` is the guard. */
9
+ type Float16ArrayConstructorLike = (new (buffer: ArrayBufferLike, byteOffset?: number, length?: number) => ArrayBufferView & {
10
+ readonly length: number;
11
+ }) & {
12
+ readonly BYTES_PER_ELEMENT: number;
13
+ };
4
14
  declare const typedArrayConstructorsByName: {
5
15
  readonly Int8Array: Int8ArrayConstructor;
6
16
  readonly Uint8Array: Uint8ArrayConstructor;
@@ -9,7 +19,7 @@ declare const typedArrayConstructorsByName: {
9
19
  readonly Uint16Array: Uint16ArrayConstructor;
10
20
  readonly Int32Array: Int32ArrayConstructor;
11
21
  readonly Uint32Array: Uint32ArrayConstructor;
12
- readonly Float16Array: Float16ArrayConstructor | undefined;
22
+ readonly Float16Array: Float16ArrayConstructorLike | undefined;
13
23
  readonly Float32Array: Float32ArrayConstructor;
14
24
  readonly Float64Array: Float64ArrayConstructor;
15
25
  readonly BigInt64Array: BigInt64ArrayConstructor;
@@ -37,9 +47,6 @@ type AnyConstructor = abstract new (...args: any[]) => unknown;
37
47
  * Tolerates undefined entries (constructors missing on this platform). */
38
48
  export declare const instanceOfAny: (value: unknown, ctors: readonly (AnyConstructor | undefined)[]) => boolean;
39
49
  export declare const isSharedArrayBuffer: (value: unknown) => boolean;
40
- /** @deprecated Renamed - this only ever checked SharedArrayBuffer, unlike
41
- * the unrelated clonable fallback module. Use isSharedArrayBuffer. */
42
- export declare const isClonable: typeof isSharedArrayBuffer;
43
50
  export declare const isTransferable: (value: unknown) => value is Transferable;
44
51
  export type { WebExtRuntime, WebExtPort, WebExtSender, WebExtOnConnect, WebExtOnMessage, WebExtEvent, WebExtGlobal } from './webext-types.js';
45
52
  export declare const isWebExtensionRuntime: (value: unknown) => value is WebExtRuntime;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osra",
3
- "version": "0.6.8",
3
+ "version": "0.6.10",
4
4
  "description": "Easy communication between workers",
5
5
  "homepage": "https://github.com/Banou26/osra#readme",
6
6
  "bugs": {
@@ -50,11 +50,14 @@
50
50
  "print-coverage": "npx nyc report",
51
51
  "clean-coverage": "node -e \"for (const dir of ['.nyc_output', 'coverage']) require('node:fs').rmSync(dir, { recursive: true, force: true })\"",
52
52
  "type-check": "node ./node_modules/typescript7/bin/tsc --noEmit && node ./node_modules/typescript7/bin/tsc --noEmit -p tsconfig.tests.json",
53
+ "lint": "vp lint",
54
+ "format": "vp fmt",
53
55
  "start-server": "http-server -p 3000",
54
56
  "build-extension-test": "node build-extension-test.mjs",
55
57
  "test-extension": "npm run build-extension-test && npx playwright test -c playwright.extension.config.ts",
56
58
  "check-consumer-types": "npm run build && node ./node_modules/typescript7/bin/tsc --noEmit -p tsconfig.consumer.json",
57
59
  "check-declaration-imports": "node scripts/check-declaration-imports.mjs",
60
+ "check-consumer-types-legacy-lib": "npm run build && node ./node_modules/typescript7/bin/tsc --noEmit -p tsconfig.consumer-lib.json",
58
61
  "docs-dev": "npm run dev -w docs",
59
62
  "docs-build": "npm run build -w docs",
60
63
  "docs-preview": "npm run preview -w docs",