adnbn 0.6.1 → 0.7.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/dist/cli/builders/csp/AbstractCsp.d.ts +9 -0
- package/dist/cli/builders/csp/AbstractCsp.js +26 -0
- package/dist/cli/builders/csp/AbstractCsp.js.map +1 -0
- package/dist/cli/builders/csp/Csp.d.ts +8 -0
- package/dist/cli/builders/csp/Csp.js +39 -0
- package/dist/cli/builders/csp/Csp.js.map +1 -0
- package/dist/cli/builders/csp/SandboxCsp.d.ts +11 -0
- package/dist/cli/builders/csp/SandboxCsp.js +62 -0
- package/dist/cli/builders/csp/SandboxCsp.js.map +1 -0
- package/dist/cli/builders/csp/index.d.ts +3 -0
- package/dist/cli/builders/csp/index.js +7 -0
- package/dist/cli/builders/csp/index.js.map +1 -0
- package/dist/cli/builders/csp/types.d.ts +4 -0
- package/dist/cli/builders/csp/types.js +1 -0
- package/dist/cli/builders/csp/types.js.map +1 -0
- package/dist/cli/builders/manifest/ManifestBase.d.ts +16 -1
- package/dist/cli/builders/manifest/ManifestBase.js +49 -0
- package/dist/cli/builders/manifest/ManifestBase.js.map +1 -1
- package/dist/cli/builders/manifest/ManifestV2.d.ts +2 -0
- package/dist/cli/builders/manifest/ManifestV2.js +31 -1
- package/dist/cli/builders/manifest/ManifestV2.js.map +1 -1
- package/dist/cli/builders/manifest/ManifestV3.d.ts +2 -0
- package/dist/cli/builders/manifest/ManifestV3.js +67 -0
- package/dist/cli/builders/manifest/ManifestV3.js.map +1 -1
- package/dist/cli/entrypoint/file/injectors/core.js +26 -0
- package/dist/cli/entrypoint/file/injectors/core.js.map +1 -1
- package/dist/cli/entrypoint/file/parsers/TypeResolver.d.ts +4 -0
- package/dist/cli/entrypoint/file/parsers/TypeResolver.js +7 -1
- package/dist/cli/entrypoint/file/parsers/TypeResolver.js.map +1 -1
- package/dist/cli/entrypoint/file/resolvers/ImportResolver.js +1 -1
- package/dist/cli/entrypoint/file/resolvers/ImportResolver.js.map +1 -1
- package/dist/cli/entrypoint/finder/OffscreenViewFinder.d.ts +2 -2
- package/dist/cli/entrypoint/finder/OffscreenViewFinder.js +2 -2
- package/dist/cli/entrypoint/finder/OffscreenViewFinder.js.map +1 -1
- package/dist/cli/entrypoint/finder/PageFinder.d.ts +2 -2
- package/dist/cli/entrypoint/finder/PageFinder.js +3 -3
- package/dist/cli/entrypoint/finder/PageFinder.js.map +1 -1
- package/dist/cli/entrypoint/finder/PopupFinder.d.ts +2 -2
- package/dist/cli/entrypoint/finder/PopupFinder.js +2 -2
- package/dist/cli/entrypoint/finder/PopupFinder.js.map +1 -1
- package/dist/cli/entrypoint/finder/SandboxFinder.d.ts +11 -0
- package/dist/cli/entrypoint/finder/SandboxFinder.js +25 -0
- package/dist/cli/entrypoint/finder/SandboxFinder.js.map +1 -0
- package/dist/cli/entrypoint/finder/SandboxViewFinder.d.ts +15 -0
- package/dist/cli/entrypoint/finder/SandboxViewFinder.js +33 -0
- package/dist/cli/entrypoint/finder/SandboxViewFinder.js.map +1 -0
- package/dist/cli/entrypoint/finder/SidebarFinder.d.ts +2 -2
- package/dist/cli/entrypoint/finder/SidebarFinder.js +2 -2
- package/dist/cli/entrypoint/finder/SidebarFinder.js.map +1 -1
- package/dist/cli/entrypoint/finder/ViewCspFinder.d.ts +11 -0
- package/dist/cli/entrypoint/finder/ViewCspFinder.js +24 -0
- package/dist/cli/entrypoint/finder/ViewCspFinder.js.map +1 -0
- package/dist/cli/entrypoint/finder/index.d.ts +3 -0
- package/dist/cli/entrypoint/finder/index.js +34 -28
- package/dist/cli/entrypoint/finder/index.js.map +1 -1
- package/dist/cli/entrypoint/parser/OffscreenParser.d.ts +2 -2
- package/dist/cli/entrypoint/parser/OffscreenParser.js +2 -2
- package/dist/cli/entrypoint/parser/OffscreenParser.js.map +1 -1
- package/dist/cli/entrypoint/parser/PageParser.d.ts +2 -2
- package/dist/cli/entrypoint/parser/PageParser.js +2 -2
- package/dist/cli/entrypoint/parser/PageParser.js.map +1 -1
- package/dist/cli/entrypoint/parser/PopupParser.d.ts +2 -2
- package/dist/cli/entrypoint/parser/PopupParser.js +2 -2
- package/dist/cli/entrypoint/parser/PopupParser.js.map +1 -1
- package/dist/cli/entrypoint/parser/SandboxParser.d.ts +7 -0
- package/dist/cli/entrypoint/parser/SandboxParser.js +42 -0
- package/dist/cli/entrypoint/parser/SandboxParser.js.map +1 -0
- package/dist/cli/entrypoint/parser/SidebarParser.d.ts +2 -2
- package/dist/cli/entrypoint/parser/SidebarParser.js +2 -2
- package/dist/cli/entrypoint/parser/SidebarParser.js.map +1 -1
- package/dist/cli/entrypoint/parser/ViewCspParser.d.ts +9 -0
- package/dist/cli/entrypoint/parser/ViewCspParser.js +26 -0
- package/dist/cli/entrypoint/parser/ViewCspParser.js.map +1 -0
- package/dist/cli/entrypoint/parser/ViewParser.d.ts +80 -80
- package/dist/cli/entrypoint/parser/index.d.ts +1 -0
- package/dist/cli/entrypoint/parser/index.js +8 -6
- package/dist/cli/entrypoint/parser/index.js.map +1 -1
- package/dist/cli/plugins/index.d.ts +2 -1
- package/dist/cli/plugins/index.js +14 -12
- package/dist/cli/plugins/index.js.map +1 -1
- package/dist/cli/plugins/offscreen/index.js +1 -0
- package/dist/cli/plugins/offscreen/index.js.map +1 -1
- package/dist/cli/plugins/page/index.js +1 -1
- package/dist/cli/plugins/page/index.js.map +1 -1
- package/dist/cli/plugins/popup/index.js +1 -1
- package/dist/cli/plugins/popup/index.js.map +1 -1
- package/dist/cli/plugins/sandbox/Sandbox.d.ts +15 -0
- package/dist/cli/plugins/sandbox/Sandbox.js +52 -0
- package/dist/cli/plugins/sandbox/Sandbox.js.map +1 -0
- package/dist/cli/plugins/sandbox/SandboxDeclaration.d.ts +5 -0
- package/dist/cli/plugins/sandbox/SandboxDeclaration.js +10 -0
- package/dist/cli/plugins/sandbox/SandboxDeclaration.js.map +1 -0
- package/dist/cli/plugins/sandbox/index.d.ts +2 -0
- package/dist/cli/plugins/sandbox/index.js +63 -0
- package/dist/cli/plugins/sandbox/index.js.map +1 -0
- package/dist/cli/plugins/sidebar/index.js +1 -0
- package/dist/cli/plugins/sidebar/index.js.map +1 -1
- package/dist/cli/plugins/style/index.d.ts +2 -0
- package/dist/cli/plugins/{style.js → style/index.js} +18 -21
- package/dist/cli/plugins/style/index.js.map +1 -0
- package/dist/cli/plugins/style/utils.d.ts +1 -0
- package/dist/cli/plugins/style/utils.js +86 -0
- package/dist/cli/plugins/style/utils.js.map +1 -0
- package/dist/cli/plugins/typescript/declaration/transport/TransportDeclaration.d.ts +2 -1
- package/dist/cli/plugins/typescript/declaration/transport/TransportDeclaration.js +1 -0
- package/dist/cli/plugins/typescript/declaration/transport/TransportDeclaration.js.map +1 -1
- package/dist/cli/resolvers/config.js +4 -0
- package/dist/cli/resolvers/config.js.map +1 -1
- package/dist/cli/virtual/index.d.ts +1 -0
- package/dist/cli/virtual/index.js +8 -1
- package/dist/cli/virtual/sandbox.d.ts +1 -0
- package/dist/cli/virtual/virtual.d.ts +27 -0
- package/dist/entry/sandbox/Builder.d.ts +15 -0
- package/dist/entry/sandbox/Builder.js +51 -0
- package/dist/entry/sandbox/Builder.js.map +1 -0
- package/dist/entry/sandbox/TransportBuilder.d.ts +8 -0
- package/dist/entry/sandbox/TransportBuilder.js +15 -0
- package/dist/entry/sandbox/TransportBuilder.js.map +1 -0
- package/dist/entry/sandbox/index.d.ts +2 -0
- package/dist/entry/sandbox/index.js +7 -0
- package/dist/entry/sandbox/index.js.map +1 -0
- package/dist/frame/ReadyFrame.d.ts +25 -0
- package/dist/frame/ReadyFrame.js +86 -0
- package/dist/frame/ReadyFrame.js.map +1 -0
- package/dist/frame/index.d.ts +2 -0
- package/dist/frame/index.js +5 -0
- package/dist/frame/index.js.map +1 -0
- package/dist/main/csp.d.ts +2 -0
- package/dist/main/csp.js +5 -0
- package/dist/main/csp.js.map +1 -0
- package/dist/main/index.d.ts +2 -0
- package/dist/main/index.js +2 -0
- package/dist/main/index.js.map +1 -1
- package/dist/main/sandbox.d.ts +9 -0
- package/dist/main/sandbox.js +29 -0
- package/dist/main/sandbox.js.map +1 -0
- package/dist/message/MessageManager.d.ts +0 -3
- package/dist/message/MessageManager.js +2 -24
- package/dist/message/MessageManager.js.map +1 -1
- package/dist/message/error.d.ts +12 -0
- package/dist/message/error.js +55 -0
- package/dist/message/error.js.map +1 -0
- package/dist/message/providers/Message.d.ts +0 -2
- package/dist/message/providers/Message.js +2 -28
- package/dist/message/providers/Message.js.map +1 -1
- package/dist/offscreen/OffscreenBridge.d.ts +1 -3
- package/dist/offscreen/OffscreenBridge.js +12 -56
- package/dist/offscreen/OffscreenBridge.js.map +1 -1
- package/dist/sandbox/SandboxFrame.d.ts +6 -0
- package/dist/sandbox/SandboxFrame.js +31 -0
- package/dist/sandbox/SandboxFrame.js.map +1 -0
- package/dist/sandbox/SandboxManager.d.ts +5 -0
- package/dist/sandbox/SandboxManager.js +12 -0
- package/dist/sandbox/SandboxManager.js.map +1 -0
- package/dist/sandbox/SandboxMessage.d.ts +30 -0
- package/dist/sandbox/SandboxMessage.js +127 -0
- package/dist/sandbox/SandboxMessage.js.map +1 -0
- package/dist/sandbox/index.d.ts +7 -0
- package/dist/sandbox/index.js +6 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/ports/SandboxHost.d.ts +21 -0
- package/dist/sandbox/ports/SandboxHost.js +58 -0
- package/dist/sandbox/ports/SandboxHost.js.map +1 -0
- package/dist/sandbox/ports/SandboxInner.d.ts +17 -0
- package/dist/sandbox/ports/SandboxInner.js +45 -0
- package/dist/sandbox/ports/SandboxInner.js.map +1 -0
- package/dist/sandbox/ports/SandboxMemory.d.ts +4 -0
- package/dist/sandbox/ports/SandboxMemory.js +42 -0
- package/dist/sandbox/ports/SandboxMemory.js.map +1 -0
- package/dist/sandbox/ports/index.d.ts +3 -0
- package/dist/sandbox/ports/index.js +9 -0
- package/dist/sandbox/ports/index.js.map +1 -0
- package/dist/sandbox/providers/ProxySandbox.d.ts +10 -0
- package/dist/sandbox/providers/ProxySandbox.js +20 -0
- package/dist/sandbox/providers/ProxySandbox.js.map +1 -0
- package/dist/sandbox/providers/RegisterSandbox.d.ts +9 -0
- package/dist/sandbox/providers/RegisterSandbox.js +28 -0
- package/dist/sandbox/providers/RegisterSandbox.js.map +1 -0
- package/dist/sandbox/providers/index.d.ts +2 -0
- package/dist/sandbox/providers/index.js +7 -0
- package/dist/sandbox/providers/index.js.map +1 -0
- package/dist/sandbox/utils.d.ts +4 -0
- package/dist/sandbox/utils.js +10 -0
- package/dist/sandbox/utils.js.map +1 -0
- package/dist/transport/RegisterTransport.d.ts +4 -2
- package/dist/transport/RegisterTransport.js +8 -1
- package/dist/transport/RegisterTransport.js.map +1 -1
- package/dist/transport/TransportMessage.d.ts +1 -1
- package/dist/transport/TransportMessage.js +1 -1
- package/dist/transport/TransportMessage.js.map +1 -1
- package/dist/types/config.d.ts +7 -0
- package/dist/types/csp.d.ts +34 -0
- package/dist/types/csp.js +12 -0
- package/dist/types/csp.js.map +1 -0
- package/dist/types/entrypoint.d.ts +2 -1
- package/dist/types/entrypoint.js +1 -0
- package/dist/types/entrypoint.js.map +1 -1
- package/dist/types/manifest.d.ts +10 -0
- package/dist/types/manifest.js.map +1 -1
- package/dist/types/offscreen.d.ts +2 -1
- package/dist/types/offscreen.js.map +1 -1
- package/dist/types/page.d.ts +2 -1
- package/dist/types/plugin.d.ts +2 -1
- package/dist/types/popup.d.ts +2 -1
- package/dist/types/sandbox.d.ts +97 -0
- package/dist/types/sandbox.js +34 -0
- package/dist/types/sandbox.js.map +1 -0
- package/dist/types/sidebar.d.ts +2 -1
- package/dist/types/sidebar.js.map +1 -1
- package/dist/types/transport.d.ts +6 -2
- package/package.json +7 -1
- package/dist/cli/plugins/style.d.ts +0 -2
- package/dist/cli/plugins/style.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/message/providers/Message.ts"],"sourcesContent":["import {sendMessage, sendTabMessage} from \"@addon-core/browser\";\n\nimport {isBrowser} from \"@main/env\";\n\nimport {\n MessageBody,\n MessageData,\n MessageDictionary,\n MessageError,\n MessageGeneralHandler,\n MessageHandler,\n MessageMapHandler,\n MessageResult,\n MessageResultEnvelopeProperty,\n MessageResponse,\n MessageSendOptions,\n MessageTargetHandler,\n MessageType,\n} from \"@typing/message\";\nimport {Browser} from \"@typing/browser\";\n\nimport AbstractMessage from \"./AbstractMessage\";\nimport MessageManager from \"../MessageManager\";\n\nimport {GeneralHandler, MapHandler, SingleHandler} from \"../handlers\";\n\nexport default class Message<T extends MessageDictionary> extends AbstractMessage<T, MessageSendOptions> {\n private static instance: Message<MessageDictionary> | null = null;\n\n public static getInstance<T extends MessageDictionary>() {\n return (this.instance ??= new Message<T>());\n }\n\n protected get manager(): MessageManager<T> {\n return MessageManager.getInstance<T>();\n }\n\n public async send<K extends MessageType<T>>(\n type: K,\n data: MessageData<T, K>,\n options?: MessageSendOptions\n ): Promise<MessageResponse<T, K>> {\n const message = this.buildMessage(type, data);\n const response = await this.dispatch(message, options);\n\n return this.unwrap(response);\n }\n\n private dispatch<K extends MessageType<T>>(\n message: MessageBody<T, K>,\n options?: MessageSendOptions\n ): Promise<MessageResult<MessageResponse<T, K>> | MessageResponse<T, K> | undefined> {\n if (options === undefined) {\n return sendMessage(message);\n }\n\n if (typeof options === \"number\") {\n return sendTabMessage(options, message);\n }\n\n const {tabId, ...other} = options;\n\n if (isBrowser(Browser.Firefox)) {\n delete other.documentId;\n }\n\n return sendTabMessage(tabId, message, other);\n }\n\n private unwrap<K extends MessageType<T>>(\n response: MessageResult<MessageResponse<T, K>> | MessageResponse<T, K> | undefined\n ): MessageResponse<T, K> {\n if (!this.isMessageResult(response)) {\n return response as MessageResponse<T, K>;\n }\n\n if (response.ok) {\n return response.payload;\n }\n\n throw
|
|
1
|
+
{"version":3,"sources":["../../../src/message/providers/Message.ts"],"sourcesContent":["import {sendMessage, sendTabMessage} from \"@addon-core/browser\";\n\nimport {restoreError} from \"../error\";\n\nimport {isBrowser} from \"@main/env\";\n\nimport {\n MessageBody,\n MessageData,\n MessageDictionary,\n MessageError,\n MessageGeneralHandler,\n MessageHandler,\n MessageMapHandler,\n MessageResult,\n MessageResultEnvelopeProperty,\n MessageResponse,\n MessageSendOptions,\n MessageTargetHandler,\n MessageType,\n} from \"@typing/message\";\nimport {Browser} from \"@typing/browser\";\n\nimport AbstractMessage from \"./AbstractMessage\";\nimport MessageManager from \"../MessageManager\";\n\nimport {GeneralHandler, MapHandler, SingleHandler} from \"../handlers\";\n\nexport default class Message<T extends MessageDictionary> extends AbstractMessage<T, MessageSendOptions> {\n private static instance: Message<MessageDictionary> | null = null;\n\n public static getInstance<T extends MessageDictionary>() {\n return (this.instance ??= new Message<T>());\n }\n\n protected get manager(): MessageManager<T> {\n return MessageManager.getInstance<T>();\n }\n\n public async send<K extends MessageType<T>>(\n type: K,\n data: MessageData<T, K>,\n options?: MessageSendOptions\n ): Promise<MessageResponse<T, K>> {\n const message = this.buildMessage(type, data);\n const response = await this.dispatch(message, options);\n\n return this.unwrap(response);\n }\n\n private dispatch<K extends MessageType<T>>(\n message: MessageBody<T, K>,\n options?: MessageSendOptions\n ): Promise<MessageResult<MessageResponse<T, K>> | MessageResponse<T, K> | undefined> {\n if (options === undefined) {\n return sendMessage(message);\n }\n\n if (typeof options === \"number\") {\n return sendTabMessage(options, message);\n }\n\n const {tabId, ...other} = options;\n\n if (isBrowser(Browser.Firefox)) {\n delete other.documentId;\n }\n\n return sendTabMessage(tabId, message, other);\n }\n\n private unwrap<K extends MessageType<T>>(\n response: MessageResult<MessageResponse<T, K>> | MessageResponse<T, K> | undefined\n ): MessageResponse<T, K> {\n if (!this.isMessageResult(response)) {\n return response as MessageResponse<T, K>;\n }\n\n if (response.ok) {\n return response.payload;\n }\n\n throw restoreError(response.error);\n }\n\n private isMessageResult(response: unknown): response is MessageResult {\n if (\n !this.isRecord(response) ||\n response[MessageResultEnvelopeProperty] !== true ||\n typeof response.ok !== \"boolean\"\n ) {\n return false;\n }\n\n if (response.ok) {\n return \"payload\" in response;\n }\n\n return this.isSerializedError(response.error);\n }\n\n private isSerializedError(error: unknown): error is MessageError {\n return (\n this.isRecord(error) &&\n typeof error.name === \"string\" &&\n typeof error.message === \"string\" &&\n (error.stack === undefined || typeof error.stack === \"string\")\n );\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n }\n\n public watch<K extends MessageType<T>>(\n arg1: K | MessageMapHandler<T> | MessageGeneralHandler<T, K>,\n arg2?: MessageTargetHandler<T, K>\n ): () => void {\n let handler: MessageHandler<T>;\n\n if (typeof arg1 === \"function\") {\n handler = new GeneralHandler<T, K>(arg1);\n } else if (typeof arg1 === \"object\" && arg2 === undefined) {\n handler = new MapHandler<T>(arg1);\n } else if (typeof arg1 === \"string\" && arg2) {\n handler = new SingleHandler<T>(arg1, arg2);\n } else {\n throw new Error(\"Invalid arguments passed to watch()\");\n }\n\n this.manager.add(handler);\n\n return () => this.manager.remove(handler);\n }\n}\n"],"mappings":"AAAA,SAAQ,aAAa,sBAAqB;AAE1C,SAAQ,oBAAmB;AAE3B,SAAQ,iBAAgB;AAExB;AAAA,EASI;AAAA,OAKG;AACP,SAAQ,eAAc;AAEtB,OAAO,qBAAqB;AAC5B,OAAO,oBAAoB;AAE3B,SAAQ,gBAAgB,YAAY,qBAAoB;AAExD,MAAO,gBAA2D,gBAAuC;AAAA,EACrG,OAAe,WAA8C;AAAA,EAE7D,OAAc,cAA2C;AACrD,WAAQ,KAAK,aAAL,KAAK,WAAa,IAAI,QAAW;AAAA,EAC7C;AAAA,EAEA,IAAc,UAA6B;AACvC,WAAO,eAAe,YAAe;AAAA,EACzC;AAAA,EAEA,MAAa,KACT,MACA,MACA,SAC8B;AAC9B,UAAM,UAAU,KAAK,aAAa,MAAM,IAAI;AAC5C,UAAM,WAAW,MAAM,KAAK,SAAS,SAAS,OAAO;AAErD,WAAO,KAAK,OAAO,QAAQ;AAAA,EAC/B;AAAA,EAEQ,SACJ,SACA,SACiF;AACjF,QAAI,YAAY,QAAW;AACvB,aAAO,YAAY,OAAO;AAAA,IAC9B;AAEA,QAAI,OAAO,YAAY,UAAU;AAC7B,aAAO,eAAe,SAAS,OAAO;AAAA,IAC1C;AAEA,UAAM,EAAC,OAAO,GAAG,MAAK,IAAI;AAE1B,QAAI,UAAU,QAAQ,OAAO,GAAG;AAC5B,aAAO,MAAM;AAAA,IACjB;AAEA,WAAO,eAAe,OAAO,SAAS,KAAK;AAAA,EAC/C;AAAA,EAEQ,OACJ,UACqB;AACrB,QAAI,CAAC,KAAK,gBAAgB,QAAQ,GAAG;AACjC,aAAO;AAAA,IACX;AAEA,QAAI,SAAS,IAAI;AACb,aAAO,SAAS;AAAA,IACpB;AAEA,UAAM,aAAa,SAAS,KAAK;AAAA,EACrC;AAAA,EAEQ,gBAAgB,UAA8C;AAClE,QACI,CAAC,KAAK,SAAS,QAAQ,KACvB,SAAS,6BAA6B,MAAM,QAC5C,OAAO,SAAS,OAAO,WACzB;AACE,aAAO;AAAA,IACX;AAEA,QAAI,SAAS,IAAI;AACb,aAAO,aAAa;AAAA,IACxB;AAEA,WAAO,KAAK,kBAAkB,SAAS,KAAK;AAAA,EAChD;AAAA,EAEQ,kBAAkB,OAAuC;AAC7D,WACI,KAAK,SAAS,KAAK,KACnB,OAAO,MAAM,SAAS,YACtB,OAAO,MAAM,YAAY,aACxB,MAAM,UAAU,UAAa,OAAO,MAAM,UAAU;AAAA,EAE7D;AAAA,EAEQ,SAAS,OAAkD;AAC/D,WAAO,OAAO,UAAU,YAAY,UAAU;AAAA,EAClD;AAAA,EAEO,MACH,MACA,MACU;AACV,QAAI;AAEJ,QAAI,OAAO,SAAS,YAAY;AAC5B,gBAAU,IAAI,eAAqB,IAAI;AAAA,IAC3C,WAAW,OAAO,SAAS,YAAY,SAAS,QAAW;AACvD,gBAAU,IAAI,WAAc,IAAI;AAAA,IACpC,WAAW,OAAO,SAAS,YAAY,MAAM;AACzC,gBAAU,IAAI,cAAiB,MAAM,IAAI;AAAA,IAC7C,OAAO;AACH,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACzD;AAEA,SAAK,QAAQ,IAAI,OAAO;AAExB,WAAO,MAAM,KAAK,QAAQ,OAAO,OAAO;AAAA,EAC5C;AACJ;","names":[]}
|
|
@@ -4,13 +4,11 @@ export default class OffscreenBridge {
|
|
|
4
4
|
protected readonly key: string;
|
|
5
5
|
protected readonly message: Message<import("../message/index.js").MessageDictionary>;
|
|
6
6
|
protected readonly readyTimeout = 10000;
|
|
7
|
-
private readonly
|
|
7
|
+
private readonly frames;
|
|
8
8
|
private static instance?;
|
|
9
9
|
static getInstance(): OffscreenBridge;
|
|
10
10
|
static createOffscreen(parameters: CreateParameters): Promise<void>;
|
|
11
11
|
create(parameters: CreateParameters): Promise<any>;
|
|
12
12
|
protected apply({ url }: CreateParameters): Promise<void>;
|
|
13
|
-
private createFrame;
|
|
14
|
-
private getFrame;
|
|
15
13
|
}
|
|
16
14
|
export {};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { isBackground } from "@addon-core/browser";
|
|
2
2
|
import { Message } from "./../message/providers/index.js";
|
|
3
|
+
import { ReadyFrame } from "./../frame/index.js";
|
|
3
4
|
import { OffscreenBridgeReadyMessageType } from "./../types/offscreen.js";
|
|
4
5
|
class OffscreenBridge {
|
|
5
6
|
key = "offscreen-background";
|
|
6
7
|
message = new Message();
|
|
7
8
|
readyTimeout = 1e4;
|
|
8
|
-
|
|
9
|
+
frames = new ReadyFrame();
|
|
9
10
|
static instance;
|
|
10
11
|
static getInstance() {
|
|
11
12
|
return OffscreenBridge.instance ?? (OffscreenBridge.instance = new OffscreenBridge());
|
|
@@ -20,64 +21,19 @@ class OffscreenBridge {
|
|
|
20
21
|
}
|
|
21
22
|
await this.message.send(this.key, parameters);
|
|
22
23
|
}
|
|
23
|
-
apply({ url }) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if ((existing == null ? void 0 : existing.dataset.ready) === "true") {
|
|
30
|
-
return Promise.resolve();
|
|
31
|
-
}
|
|
32
|
-
const creation = this.createFrame(url, existing).finally(() => {
|
|
33
|
-
this.framesReady.delete(url);
|
|
34
|
-
});
|
|
35
|
-
this.framesReady.set(url, creation);
|
|
36
|
-
return creation;
|
|
37
|
-
}
|
|
38
|
-
createFrame(url, existing) {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
const iframe = existing ?? document.createElement("iframe");
|
|
41
|
-
const cleanup = () => {
|
|
42
|
-
clearTimeout(timeout);
|
|
43
|
-
window.removeEventListener("message", listener);
|
|
44
|
-
iframe.onerror = null;
|
|
45
|
-
};
|
|
46
|
-
const listener = (event) => {
|
|
24
|
+
async apply({ url }) {
|
|
25
|
+
await this.frames.make({
|
|
26
|
+
key: url,
|
|
27
|
+
url,
|
|
28
|
+
readyTimeout: this.readyTimeout,
|
|
29
|
+
isReady: (event, frame) => {
|
|
47
30
|
var _a;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (((_a = event.data) == null ? void 0 : _a.type) !== OffscreenBridgeReadyMessageType) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
iframe.dataset.ready = "true";
|
|
58
|
-
cleanup();
|
|
59
|
-
resolve();
|
|
60
|
-
};
|
|
61
|
-
const timeout = setTimeout(() => {
|
|
62
|
-
cleanup();
|
|
63
|
-
iframe.remove();
|
|
64
|
-
reject(new Error(`Offscreen iframe "${url}" was not ready in time.`));
|
|
65
|
-
}, this.readyTimeout);
|
|
66
|
-
iframe.onerror = () => {
|
|
67
|
-
cleanup();
|
|
68
|
-
iframe.remove();
|
|
69
|
-
reject(new Error(`Offscreen iframe failed to load: ${url}`));
|
|
70
|
-
};
|
|
71
|
-
window.addEventListener("message", listener);
|
|
72
|
-
if (!existing) {
|
|
73
|
-
iframe.src = url;
|
|
74
|
-
document.body.appendChild(iframe);
|
|
75
|
-
}
|
|
31
|
+
return event.source === frame.contentWindow && event.origin === location.origin && ((_a = event.data) == null ? void 0 : _a.type) === OffscreenBridgeReadyMessageType;
|
|
32
|
+
},
|
|
33
|
+
readyTimeoutMessage: () => `Offscreen iframe "${url}" was not ready in time.`,
|
|
34
|
+
loadErrorMessage: () => `Offscreen iframe failed to load: ${url}`
|
|
76
35
|
});
|
|
77
36
|
}
|
|
78
|
-
getFrame(url) {
|
|
79
|
-
return Array.from(document.querySelectorAll("iframe")).find((iframe) => iframe.getAttribute("src") === url);
|
|
80
|
-
}
|
|
81
37
|
}
|
|
82
38
|
export {
|
|
83
39
|
OffscreenBridge as default
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/offscreen/OffscreenBridge.ts"],"sourcesContent":["import {isBackground} from \"@addon-core/browser\";\n\nimport {Message} from \"@message/providers\";\n\nimport {OffscreenBridgeReadyMessageType} from \"@typing/offscreen\";\n\ntype CreateParameters = chrome.offscreen.CreateParameters;\n\nexport default class OffscreenBridge {\n protected readonly key: string = \"offscreen-background\";\n\n protected readonly message = new Message();\n\n protected readonly readyTimeout = 10000;\n\n private readonly
|
|
1
|
+
{"version":3,"sources":["../../src/offscreen/OffscreenBridge.ts"],"sourcesContent":["import {isBackground} from \"@addon-core/browser\";\n\nimport {Message} from \"@message/providers\";\nimport {ReadyFrame} from \"@frame/index\";\n\nimport {OffscreenBridgeReadyMessageType} from \"@typing/offscreen\";\n\ntype CreateParameters = chrome.offscreen.CreateParameters;\n\nexport default class OffscreenBridge {\n protected readonly key: string = \"offscreen-background\";\n\n protected readonly message = new Message();\n\n protected readonly readyTimeout = 10000;\n\n private readonly frames = new ReadyFrame();\n\n private static instance?: OffscreenBridge;\n\n public static getInstance(): OffscreenBridge {\n return (OffscreenBridge.instance ??= new OffscreenBridge());\n }\n\n public static async createOffscreen(parameters: CreateParameters): Promise<void> {\n return OffscreenBridge.getInstance().create(parameters);\n }\n\n public async create(parameters: CreateParameters): Promise<any> {\n if (isBackground()) {\n await this.apply(parameters);\n\n return;\n }\n\n await this.message.send(this.key, parameters);\n }\n\n protected async apply({url}: CreateParameters): Promise<void> {\n await this.frames.make({\n key: url,\n url,\n readyTimeout: this.readyTimeout,\n isReady: (event, frame) =>\n event.source === frame.contentWindow &&\n event.origin === location.origin &&\n event.data?.type === OffscreenBridgeReadyMessageType,\n readyTimeoutMessage: () => `Offscreen iframe \"${url}\" was not ready in time.`,\n loadErrorMessage: () => `Offscreen iframe failed to load: ${url}`,\n });\n }\n}\n"],"mappings":"AAAA,SAAQ,oBAAmB;AAE3B,SAAQ,eAAc;AACtB,SAAQ,kBAAiB;AAEzB,SAAQ,uCAAsC;AAI9C,MAAO,gBAA8B;AAAA,EACd,MAAc;AAAA,EAEd,UAAU,IAAI,QAAQ;AAAA,EAEtB,eAAe;AAAA,EAEjB,SAAS,IAAI,WAAW;AAAA,EAEzC,OAAe;AAAA,EAEf,OAAc,cAA+B;AACzC,WAAQ,gBAAgB,aAAhB,gBAAgB,WAAa,IAAI,gBAAgB;AAAA,EAC7D;AAAA,EAEA,aAAoB,gBAAgB,YAA6C;AAC7E,WAAO,gBAAgB,YAAY,EAAE,OAAO,UAAU;AAAA,EAC1D;AAAA,EAEA,MAAa,OAAO,YAA4C;AAC5D,QAAI,aAAa,GAAG;AAChB,YAAM,KAAK,MAAM,UAAU;AAE3B;AAAA,IACJ;AAEA,UAAM,KAAK,QAAQ,KAAK,KAAK,KAAK,UAAU;AAAA,EAChD;AAAA,EAEA,MAAgB,MAAM,EAAC,IAAG,GAAoC;AAC1D,UAAM,KAAK,OAAO,KAAK;AAAA,MACnB,KAAK;AAAA,MACL;AAAA,MACA,cAAc,KAAK;AAAA,MACnB,SAAS,CAAC,OAAO,UAAO;AA3CpC;AA4CgB,qBAAM,WAAW,MAAM,iBACvB,MAAM,WAAW,SAAS,YAC1B,WAAM,SAAN,mBAAY,UAAS;AAAA;AAAA,MACzB,qBAAqB,MAAM,qBAAqB,GAAG;AAAA,MACnD,kBAAkB,MAAM,oCAAoC,GAAG;AAAA,IACnE,CAAC;AAAA,EACL;AACJ;","names":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { sandboxChannel } from "./utils.js";
|
|
2
|
+
import { ReadyFrame } from "./../frame/index.js";
|
|
3
|
+
import { SandboxReadyMessageType } from "./../types/sandbox.js";
|
|
4
|
+
class SandboxFrame {
|
|
5
|
+
frames = new ReadyFrame();
|
|
6
|
+
make(name, parameters) {
|
|
7
|
+
const { url, readyTimeout } = parameters;
|
|
8
|
+
const channel = sandboxChannel(name);
|
|
9
|
+
return this.frames.make({
|
|
10
|
+
key: name,
|
|
11
|
+
url,
|
|
12
|
+
readyTimeout,
|
|
13
|
+
isReady: (event, frame) => {
|
|
14
|
+
if (event.source !== frame.contentWindow) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const data = event.data;
|
|
18
|
+
return (data == null ? void 0 : data.type) === SandboxReadyMessageType && data.channel === channel && data.name === name;
|
|
19
|
+
},
|
|
20
|
+
readyTimeoutMessage: (loaded, timeout) => loaded ? `Sandbox "${name}" loaded but never signaled ready within ${timeout}ms. Ensure the sandbox entry runs and the manifest sandbox CSP allows its script.` : `Sandbox "${name}" did not load "${url}" within ${timeout}ms. Ensure the page is listed in the manifest sandbox pages and is not blocked by CSP.`,
|
|
21
|
+
loadErrorMessage: () => `Sandbox "${name}" failed to load: ${url}`
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
remove(name) {
|
|
25
|
+
this.frames.remove(name);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
SandboxFrame as default
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=SandboxFrame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/sandbox/SandboxFrame.ts"],"sourcesContent":["import {sandboxChannel} from \"./utils\";\n\nimport {ReadyFrame} from \"@frame/index\";\n\nimport {SandboxParameters, SandboxReadyMessage, SandboxReadyMessageType} from \"@typing/sandbox\";\n\nexport default class SandboxFrame {\n private readonly frames = new ReadyFrame();\n\n public make(name: string, parameters: SandboxParameters): Promise<HTMLIFrameElement> {\n const {url, readyTimeout} = parameters;\n const channel = sandboxChannel(name);\n\n return this.frames.make({\n key: name,\n url,\n readyTimeout,\n isReady: (event, frame) => {\n if (event.source !== frame.contentWindow) {\n return false;\n }\n\n const data = event.data as Partial<SandboxReadyMessage>;\n\n return data?.type === SandboxReadyMessageType && data.channel === channel && data.name === name;\n },\n readyTimeoutMessage: (loaded, timeout) =>\n loaded\n ? `Sandbox \"${name}\" loaded but never signaled ready within ${timeout}ms. Ensure the sandbox entry runs and the manifest sandbox CSP allows its script.`\n : `Sandbox \"${name}\" did not load \"${url}\" within ${timeout}ms. Ensure the page is listed in the manifest sandbox pages and is not blocked by CSP.`,\n loadErrorMessage: () => `Sandbox \"${name}\" failed to load: ${url}`,\n });\n }\n\n public remove(name: string): void {\n this.frames.remove(name);\n }\n}\n"],"mappings":"AAAA,SAAQ,sBAAqB;AAE7B,SAAQ,kBAAiB;AAEzB,SAAgD,+BAA8B;AAE9E,MAAO,aAA2B;AAAA,EACb,SAAS,IAAI,WAAW;AAAA,EAElC,KAAK,MAAc,YAA2D;AACjF,UAAM,EAAC,KAAK,aAAY,IAAI;AAC5B,UAAM,UAAU,eAAe,IAAI;AAEnC,WAAO,KAAK,OAAO,KAAK;AAAA,MACpB,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,SAAS,CAAC,OAAO,UAAU;AACvB,YAAI,MAAM,WAAW,MAAM,eAAe;AACtC,iBAAO;AAAA,QACX;AAEA,cAAM,OAAO,MAAM;AAEnB,gBAAO,6BAAM,UAAS,2BAA2B,KAAK,YAAY,WAAW,KAAK,SAAS;AAAA,MAC/F;AAAA,MACA,qBAAqB,CAAC,QAAQ,YAC1B,SACM,YAAY,IAAI,4CAA4C,OAAO,sFACnE,YAAY,IAAI,mBAAmB,GAAG,YAAY,OAAO;AAAA,MACnE,kBAAkB,MAAM,YAAY,IAAI,qBAAqB,GAAG;AAAA,IACpE,CAAC;AAAA,EACL;AAAA,EAEO,OAAO,MAAoB;AAC9B,SAAK,OAAO,OAAO,IAAI;AAAA,EAC3B;AACJ;","names":[]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import TransportManager from "../transport/TransportManager.js";
|
|
2
|
+
import type { TransportManager as TransportManagerContract } from "../types/transport.js";
|
|
3
|
+
export default class SandboxManager extends TransportManager {
|
|
4
|
+
static getInstance(): TransportManagerContract;
|
|
5
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import TransportManager from "./../transport/TransportManager.js";
|
|
2
|
+
import { SandboxGlobalKey } from "./../types/sandbox.js";
|
|
3
|
+
class SandboxManager extends TransportManager {
|
|
4
|
+
static getInstance() {
|
|
5
|
+
var _a;
|
|
6
|
+
return globalThis[_a = SandboxGlobalKey] ?? (globalThis[_a] = new SandboxManager());
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
SandboxManager as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=SandboxManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/sandbox/SandboxManager.ts"],"sourcesContent":["import TransportManager from \"@transport/TransportManager\";\n\nimport {SandboxGlobalKey} from \"@typing/sandbox\";\n\nimport type {TransportManager as TransportManagerContract} from \"@typing/transport\";\n\nexport default class SandboxManager extends TransportManager {\n public static getInstance(): TransportManagerContract {\n return (globalThis[SandboxGlobalKey] ??= new SandboxManager());\n }\n}\n"],"mappings":"AAAA,OAAO,sBAAsB;AAE7B,SAAQ,wBAAuB;AAI/B,MAAO,uBAAqC,iBAAiB;AAAA,EACzD,OAAc,cAAwC;AAP1D;AAQQ,WAAQ,gBAAW,sBAAX,iBAAiC,IAAI,eAAe;AAAA,EAChE;AACJ;","names":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SandboxParameters, SandboxPort } from "../types/sandbox.js";
|
|
2
|
+
import type { MessageSender } from "../types/message.js";
|
|
3
|
+
import type { TransportMessage, TransportMessageData } from "../types/transport.js";
|
|
4
|
+
/**
|
|
5
|
+
* The standard transport channel (`send`/`watch`) for the sandbox layer, implemented over
|
|
6
|
+
* `window.postMessage` instead of the chrome.runtime `Message` provider. All request/response
|
|
7
|
+
* correlation (requestId, pending map, timeouts, error serialize/restore) lives here, behind
|
|
8
|
+
* the standard interface; the raw wire sits below in a `SandboxPort`.
|
|
9
|
+
*/
|
|
10
|
+
export default class SandboxMessage implements TransportMessage {
|
|
11
|
+
private readonly name;
|
|
12
|
+
private readonly port;
|
|
13
|
+
private readonly parameters;
|
|
14
|
+
private static readonly hosts;
|
|
15
|
+
private readonly channel;
|
|
16
|
+
private readonly pending;
|
|
17
|
+
private listenUnsubscribe?;
|
|
18
|
+
private watchUnsubscribe?;
|
|
19
|
+
constructor(name: string, port: SandboxPort, parameters?: Partial<SandboxParameters>);
|
|
20
|
+
/**
|
|
21
|
+
* Host-side channel, cached per name. One cached instance means one peer listener per
|
|
22
|
+
* sandbox no matter how many times `getSandbox()` is called — this is the leak fix.
|
|
23
|
+
*/
|
|
24
|
+
static for(name: string, parameters: SandboxParameters): SandboxMessage;
|
|
25
|
+
send(data: TransportMessageData): Promise<any>;
|
|
26
|
+
watch(handler: (data: TransportMessageData, sender: MessageSender) => any): () => void;
|
|
27
|
+
dispose(): void;
|
|
28
|
+
private listen;
|
|
29
|
+
private respond;
|
|
30
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { nanoid } from "nanoid";
|
|
2
|
+
import { sandboxChannel } from "./utils.js";
|
|
3
|
+
import { SandboxHost } from "./ports/index.js";
|
|
4
|
+
import { restoreError, serializeError } from "./../message/error.js";
|
|
5
|
+
import {
|
|
6
|
+
SandboxRequestMessageType,
|
|
7
|
+
SandboxResponseMessageType
|
|
8
|
+
} from "./../types/sandbox.js";
|
|
9
|
+
const DefaultRequestTimeout = 3e4;
|
|
10
|
+
class SandboxMessage {
|
|
11
|
+
constructor(name, port, parameters = {}) {
|
|
12
|
+
this.name = name;
|
|
13
|
+
this.port = port;
|
|
14
|
+
this.parameters = parameters;
|
|
15
|
+
this.channel = sandboxChannel(name);
|
|
16
|
+
}
|
|
17
|
+
name;
|
|
18
|
+
port;
|
|
19
|
+
parameters;
|
|
20
|
+
static hosts = /* @__PURE__ */ new Map();
|
|
21
|
+
channel;
|
|
22
|
+
pending = /* @__PURE__ */ new Map();
|
|
23
|
+
listenUnsubscribe;
|
|
24
|
+
watchUnsubscribe;
|
|
25
|
+
/**
|
|
26
|
+
* Host-side channel, cached per name. One cached instance means one peer listener per
|
|
27
|
+
* sandbox no matter how many times `getSandbox()` is called — this is the leak fix.
|
|
28
|
+
*/
|
|
29
|
+
static for(name, parameters) {
|
|
30
|
+
let message = this.hosts.get(name);
|
|
31
|
+
if (!message) {
|
|
32
|
+
message = new SandboxMessage(name, new SandboxHost(name, parameters), parameters);
|
|
33
|
+
this.hosts.set(name, message);
|
|
34
|
+
}
|
|
35
|
+
return message;
|
|
36
|
+
}
|
|
37
|
+
async send(data) {
|
|
38
|
+
await this.port.connect();
|
|
39
|
+
this.listen();
|
|
40
|
+
const requestId = nanoid();
|
|
41
|
+
const request = {
|
|
42
|
+
type: SandboxRequestMessageType,
|
|
43
|
+
channel: this.channel,
|
|
44
|
+
name: this.name,
|
|
45
|
+
requestId,
|
|
46
|
+
path: data.path,
|
|
47
|
+
args: data.args
|
|
48
|
+
};
|
|
49
|
+
const requestTimeout = this.parameters.requestTimeout ?? DefaultRequestTimeout;
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
const timeout = setTimeout(() => {
|
|
52
|
+
this.pending.delete(requestId);
|
|
53
|
+
if (this.parameters.removeOnRequestTimeout && this.pending.size === 0) {
|
|
54
|
+
this.dispose();
|
|
55
|
+
}
|
|
56
|
+
reject(new Error(`Sandbox "${this.name}" request "${requestId}" timed out.`));
|
|
57
|
+
}, requestTimeout);
|
|
58
|
+
this.pending.set(requestId, { resolve, reject, timeout });
|
|
59
|
+
this.port.post(request);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
watch(handler) {
|
|
63
|
+
if (this.watchUnsubscribe) {
|
|
64
|
+
return this.watchUnsubscribe;
|
|
65
|
+
}
|
|
66
|
+
const unsubscribe = this.port.subscribe(async (message, sender) => {
|
|
67
|
+
if (message.type !== SandboxRequestMessageType) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const payload = await handler({ path: message.path, args: message.args ?? [] }, sender);
|
|
72
|
+
this.respond({ requestId: message.requestId, ok: true, payload });
|
|
73
|
+
} catch (error) {
|
|
74
|
+
this.respond({ requestId: message.requestId, ok: false, error: serializeError(error) });
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
this.watchUnsubscribe = unsubscribe;
|
|
78
|
+
return unsubscribe;
|
|
79
|
+
}
|
|
80
|
+
dispose() {
|
|
81
|
+
var _a, _b;
|
|
82
|
+
for (const pending of this.pending.values()) {
|
|
83
|
+
clearTimeout(pending.timeout);
|
|
84
|
+
pending.reject(new Error(`Sandbox "${this.name}" was disposed.`));
|
|
85
|
+
}
|
|
86
|
+
this.pending.clear();
|
|
87
|
+
(_a = this.listenUnsubscribe) == null ? void 0 : _a.call(this);
|
|
88
|
+
this.listenUnsubscribe = void 0;
|
|
89
|
+
(_b = this.watchUnsubscribe) == null ? void 0 : _b.call(this);
|
|
90
|
+
this.watchUnsubscribe = void 0;
|
|
91
|
+
this.port.dispose();
|
|
92
|
+
SandboxMessage.hosts.delete(this.name);
|
|
93
|
+
}
|
|
94
|
+
listen() {
|
|
95
|
+
if (this.listenUnsubscribe) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
this.listenUnsubscribe = this.port.subscribe((message) => {
|
|
99
|
+
if (message.type !== SandboxResponseMessageType) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const pending = this.pending.get(message.requestId);
|
|
103
|
+
if (!pending) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
clearTimeout(pending.timeout);
|
|
107
|
+
this.pending.delete(message.requestId);
|
|
108
|
+
if (message.ok) {
|
|
109
|
+
pending.resolve(message.payload);
|
|
110
|
+
} else {
|
|
111
|
+
pending.reject(restoreError(message.error));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
respond(response) {
|
|
116
|
+
this.port.post({
|
|
117
|
+
type: SandboxResponseMessageType,
|
|
118
|
+
channel: this.channel,
|
|
119
|
+
name: this.name,
|
|
120
|
+
...response
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export {
|
|
125
|
+
SandboxMessage as default
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=SandboxMessage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/sandbox/SandboxMessage.ts"],"sourcesContent":["import {nanoid} from \"nanoid\";\n\nimport {sandboxChannel} from \"./utils\";\nimport {SandboxHost} from \"./ports\";\n\nimport {restoreError, serializeError} from \"@message/error\";\nimport {\n SandboxParameters,\n SandboxPort,\n SandboxRequestMessage,\n SandboxRequestMessageType,\n SandboxResponseMessage,\n SandboxResponseMessageType,\n} from \"@typing/sandbox\";\nimport type {MessageSender} from \"@typing/message\";\nimport type {TransportMessage, TransportMessageData} from \"@typing/transport\";\n\ntype Pending = {\n resolve: (value: any) => void;\n reject: (reason?: any) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\nconst DefaultRequestTimeout = 30000;\n\n/**\n * The standard transport channel (`send`/`watch`) for the sandbox layer, implemented over\n * `window.postMessage` instead of the chrome.runtime `Message` provider. All request/response\n * correlation (requestId, pending map, timeouts, error serialize/restore) lives here, behind\n * the standard interface; the raw wire sits below in a `SandboxPort`.\n */\nexport default class SandboxMessage implements TransportMessage {\n private static readonly hosts: Map<string, SandboxMessage> = new Map();\n\n private readonly channel: string;\n\n private readonly pending: Map<string, Pending> = new Map();\n\n private listenUnsubscribe?: () => void;\n\n private watchUnsubscribe?: () => void;\n\n constructor(\n private readonly name: string,\n private readonly port: SandboxPort,\n private readonly parameters: Partial<SandboxParameters> = {}\n ) {\n this.channel = sandboxChannel(name);\n }\n\n /**\n * Host-side channel, cached per name. One cached instance means one peer listener per\n * sandbox no matter how many times `getSandbox()` is called — this is the leak fix.\n */\n public static for(name: string, parameters: SandboxParameters): SandboxMessage {\n let message = this.hosts.get(name);\n\n if (!message) {\n message = new SandboxMessage(name, new SandboxHost(name, parameters), parameters);\n\n this.hosts.set(name, message);\n }\n\n return message;\n }\n\n public async send(data: TransportMessageData): Promise<any> {\n await this.port.connect();\n\n this.listen();\n\n const requestId = nanoid();\n const request: SandboxRequestMessage = {\n type: SandboxRequestMessageType,\n channel: this.channel,\n name: this.name,\n requestId,\n path: data.path,\n args: data.args,\n };\n\n const requestTimeout = this.parameters.requestTimeout ?? DefaultRequestTimeout;\n\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(requestId);\n\n if (this.parameters.removeOnRequestTimeout && this.pending.size === 0) {\n this.dispose();\n }\n\n reject(new Error(`Sandbox \"${this.name}\" request \"${requestId}\" timed out.`));\n }, requestTimeout);\n\n this.pending.set(requestId, {resolve, reject, timeout});\n\n this.port.post(request);\n });\n }\n\n public watch(handler: (data: TransportMessageData, sender: MessageSender) => any): () => void {\n if (this.watchUnsubscribe) {\n return this.watchUnsubscribe;\n }\n\n const unsubscribe = this.port.subscribe(async (message, sender) => {\n if (message.type !== SandboxRequestMessageType) {\n return;\n }\n\n try {\n const payload = await handler({path: message.path, args: message.args ?? []}, sender);\n\n this.respond({requestId: message.requestId, ok: true, payload});\n } catch (error) {\n this.respond({requestId: message.requestId, ok: false, error: serializeError(error)});\n }\n });\n\n this.watchUnsubscribe = unsubscribe;\n\n return unsubscribe;\n }\n\n public dispose(): void {\n for (const pending of this.pending.values()) {\n clearTimeout(pending.timeout);\n pending.reject(new Error(`Sandbox \"${this.name}\" was disposed.`));\n }\n\n this.pending.clear();\n\n this.listenUnsubscribe?.();\n this.listenUnsubscribe = undefined;\n\n this.watchUnsubscribe?.();\n this.watchUnsubscribe = undefined;\n\n this.port.dispose();\n\n SandboxMessage.hosts.delete(this.name);\n }\n\n private listen(): void {\n if (this.listenUnsubscribe) {\n return;\n }\n\n this.listenUnsubscribe = this.port.subscribe(message => {\n if (message.type !== SandboxResponseMessageType) {\n return;\n }\n\n const pending = this.pending.get(message.requestId);\n\n if (!pending) {\n return;\n }\n\n clearTimeout(pending.timeout);\n this.pending.delete(message.requestId);\n\n if (message.ok) {\n pending.resolve(message.payload);\n } else {\n pending.reject(restoreError(message.error));\n }\n });\n }\n\n private respond(response: Omit<SandboxResponseMessage, \"type\" | \"channel\" | \"name\">): void {\n this.port.post({\n type: SandboxResponseMessageType,\n channel: this.channel,\n name: this.name,\n ...response,\n });\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ProxySandbox, RegisterSandbox } from "./providers/index.js";
|
|
2
|
+
import type { DeepAsyncProxy } from "../types/helpers.js";
|
|
3
|
+
export { ProxySandbox, RegisterSandbox };
|
|
4
|
+
export interface SandboxRegistry {
|
|
5
|
+
}
|
|
6
|
+
export type SandboxName = Extract<keyof SandboxRegistry, string>;
|
|
7
|
+
export type SandboxProxyTarget<N extends keyof SandboxRegistry> = DeepAsyncProxy<SandboxRegistry[N]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/sandbox/index.ts"],"sourcesContent":["import {ProxySandbox, RegisterSandbox} from \"./providers\";\n\nimport type {DeepAsyncProxy} from \"@typing/helpers\";\n\nexport {ProxySandbox, RegisterSandbox};\n\nexport interface SandboxRegistry {}\n\nexport type SandboxName = Extract<keyof SandboxRegistry, string>;\n\nexport type SandboxProxyTarget<N extends keyof SandboxRegistry> = DeepAsyncProxy<SandboxRegistry[N]>;\n"],"mappings":"AAAA,SAAQ,cAAc,uBAAsB;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SandboxEnvelope, SandboxParameters, SandboxPort } from "../../types/sandbox.js";
|
|
2
|
+
import type { MessageSender } from "../../types/message.js";
|
|
3
|
+
/**
|
|
4
|
+
* Host-side `SandboxPort`: runs in an extension page, owns the sandbox iframe.
|
|
5
|
+
* `connect` creates the iframe and awaits its ready handshake (via `SandboxFrame`);
|
|
6
|
+
* `post` targets the iframe's `contentWindow`; `subscribe` attaches a single `message`
|
|
7
|
+
* listener filtered to that frame.
|
|
8
|
+
*/
|
|
9
|
+
export default class SandboxHost implements SandboxPort {
|
|
10
|
+
private readonly name;
|
|
11
|
+
private readonly parameters;
|
|
12
|
+
private readonly frames;
|
|
13
|
+
private readonly channel;
|
|
14
|
+
private frame?;
|
|
15
|
+
private unsubscribe?;
|
|
16
|
+
constructor(name: string, parameters: SandboxParameters);
|
|
17
|
+
connect(): Promise<void>;
|
|
18
|
+
post(message: SandboxEnvelope): void;
|
|
19
|
+
subscribe(onMessage: (message: SandboxEnvelope, sender: MessageSender) => void): () => void;
|
|
20
|
+
dispose(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { sandboxChannel, sandboxSender } from "../utils.js";
|
|
2
|
+
import SandboxFrame from "../SandboxFrame.js";
|
|
3
|
+
class SandboxHost {
|
|
4
|
+
constructor(name, parameters) {
|
|
5
|
+
this.name = name;
|
|
6
|
+
this.parameters = parameters;
|
|
7
|
+
this.channel = sandboxChannel(name);
|
|
8
|
+
}
|
|
9
|
+
name;
|
|
10
|
+
parameters;
|
|
11
|
+
frames = new SandboxFrame();
|
|
12
|
+
channel;
|
|
13
|
+
frame;
|
|
14
|
+
unsubscribe;
|
|
15
|
+
async connect() {
|
|
16
|
+
this.frame = await this.frames.make(this.name, this.parameters);
|
|
17
|
+
}
|
|
18
|
+
post(message) {
|
|
19
|
+
var _a;
|
|
20
|
+
const target = (_a = this.frame) == null ? void 0 : _a.contentWindow;
|
|
21
|
+
if (!target) {
|
|
22
|
+
throw new Error(`Sandbox "${this.name}" is not available.`);
|
|
23
|
+
}
|
|
24
|
+
target.postMessage(message, "*");
|
|
25
|
+
}
|
|
26
|
+
subscribe(onMessage) {
|
|
27
|
+
if (this.unsubscribe) {
|
|
28
|
+
return this.unsubscribe;
|
|
29
|
+
}
|
|
30
|
+
const listener = (event) => {
|
|
31
|
+
var _a;
|
|
32
|
+
if (event.source !== ((_a = this.frame) == null ? void 0 : _a.contentWindow)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const data = event.data;
|
|
36
|
+
if ((data == null ? void 0 : data.channel) !== this.channel || data.name !== this.name) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
onMessage(data, sandboxSender());
|
|
40
|
+
};
|
|
41
|
+
window.addEventListener("message", listener);
|
|
42
|
+
this.unsubscribe = () => {
|
|
43
|
+
window.removeEventListener("message", listener);
|
|
44
|
+
this.unsubscribe = void 0;
|
|
45
|
+
};
|
|
46
|
+
return this.unsubscribe;
|
|
47
|
+
}
|
|
48
|
+
dispose() {
|
|
49
|
+
var _a;
|
|
50
|
+
(_a = this.unsubscribe) == null ? void 0 : _a.call(this);
|
|
51
|
+
this.frames.remove(this.name);
|
|
52
|
+
this.frame = void 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
SandboxHost as default
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=SandboxHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/sandbox/ports/SandboxHost.ts"],"sourcesContent":["import {sandboxChannel, sandboxSender} from \"../utils\";\nimport SandboxFrame from \"../SandboxFrame\";\n\nimport type {SandboxEnvelope, SandboxParameters, SandboxPort} from \"@typing/sandbox\";\nimport type {MessageSender} from \"@typing/message\";\n\n/**\n * Host-side `SandboxPort`: runs in an extension page, owns the sandbox iframe.\n * `connect` creates the iframe and awaits its ready handshake (via `SandboxFrame`);\n * `post` targets the iframe's `contentWindow`; `subscribe` attaches a single `message`\n * listener filtered to that frame.\n */\nexport default class SandboxHost implements SandboxPort {\n private readonly frames = new SandboxFrame();\n\n private readonly channel: string;\n\n private frame?: HTMLIFrameElement;\n\n private unsubscribe?: () => void;\n\n constructor(\n private readonly name: string,\n private readonly parameters: SandboxParameters\n ) {\n this.channel = sandboxChannel(name);\n }\n\n public async connect(): Promise<void> {\n this.frame = await this.frames.make(this.name, this.parameters);\n }\n\n public post(message: SandboxEnvelope): void {\n const target = this.frame?.contentWindow;\n\n if (!target) {\n throw new Error(`Sandbox \"${this.name}\" is not available.`);\n }\n\n // Sandboxed iframes have an opaque origin, so no concrete targetOrigin is possible.\n // Inbound messages are trusted by channel + name + requestId, never by origin.\n target.postMessage(message, \"*\");\n }\n\n public subscribe(onMessage: (message: SandboxEnvelope, sender: MessageSender) => void): () => void {\n if (this.unsubscribe) {\n return this.unsubscribe;\n }\n\n const listener = (event: MessageEvent) => {\n if (event.source !== this.frame?.contentWindow) {\n return;\n }\n\n const data = event.data as Partial<SandboxEnvelope>;\n\n if (data?.channel !== this.channel || data.name !== this.name) {\n return;\n }\n\n onMessage(data as SandboxEnvelope, sandboxSender());\n };\n\n window.addEventListener(\"message\", listener);\n\n this.unsubscribe = () => {\n window.removeEventListener(\"message\", listener);\n this.unsubscribe = undefined;\n };\n\n return this.unsubscribe;\n }\n\n public dispose(): void {\n this.unsubscribe?.();\n this.frames.remove(this.name);\n this.frame = undefined;\n }\n}\n"],"mappings":"AAAA,SAAQ,gBAAgB,qBAAoB;AAC5C,OAAO,kBAAkB;AAWzB,MAAO,YAAiD;AAAA,EASpD,YACqB,MACA,YACnB;AAFmB;AACA;AAEjB,SAAK,UAAU,eAAe,IAAI;AAAA,EACtC;AAAA,EAJqB;AAAA,EACA;AAAA,EAVJ,SAAS,IAAI,aAAa;AAAA,EAE1B;AAAA,EAET;AAAA,EAEA;AAAA,EASR,MAAa,UAAyB;AAClC,SAAK,QAAQ,MAAM,KAAK,OAAO,KAAK,KAAK,MAAM,KAAK,UAAU;AAAA,EAClE;AAAA,EAEO,KAAK,SAAgC;AAhChD;AAiCQ,UAAM,UAAS,UAAK,UAAL,mBAAY;AAE3B,QAAI,CAAC,QAAQ;AACT,YAAM,IAAI,MAAM,YAAY,KAAK,IAAI,qBAAqB;AAAA,IAC9D;AAIA,WAAO,YAAY,SAAS,GAAG;AAAA,EACnC;AAAA,EAEO,UAAU,WAAkF;AAC/F,QAAI,KAAK,aAAa;AAClB,aAAO,KAAK;AAAA,IAChB;AAEA,UAAM,WAAW,CAAC,UAAwB;AAjDlD;AAkDY,UAAI,MAAM,aAAW,UAAK,UAAL,mBAAY,gBAAe;AAC5C;AAAA,MACJ;AAEA,YAAM,OAAO,MAAM;AAEnB,WAAI,6BAAM,aAAY,KAAK,WAAW,KAAK,SAAS,KAAK,MAAM;AAC3D;AAAA,MACJ;AAEA,gBAAU,MAAyB,cAAc,CAAC;AAAA,IACtD;AAEA,WAAO,iBAAiB,WAAW,QAAQ;AAE3C,SAAK,cAAc,MAAM;AACrB,aAAO,oBAAoB,WAAW,QAAQ;AAC9C,WAAK,cAAc;AAAA,IACvB;AAEA,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,UAAgB;AAzE3B;AA0EQ,eAAK,gBAAL;AACA,SAAK,OAAO,OAAO,KAAK,IAAI;AAC5B,SAAK,QAAQ;AAAA,EACjB;AACJ;","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SandboxEnvelope, SandboxPort } from "../../types/sandbox.js";
|
|
2
|
+
import type { MessageSender } from "../../types/message.js";
|
|
3
|
+
/**
|
|
4
|
+
* Sandbox-side `SandboxPort`: runs inside the iframe. There is no frame to create, so
|
|
5
|
+
* `connect` resolves immediately (the ready handshake is posted by the sandbox builder);
|
|
6
|
+
* `post` targets `window.parent`; `subscribe` listens for messages from the parent.
|
|
7
|
+
*/
|
|
8
|
+
export default class SandboxInner implements SandboxPort {
|
|
9
|
+
private readonly name;
|
|
10
|
+
private readonly channel;
|
|
11
|
+
private unsubscribe?;
|
|
12
|
+
constructor(name: string);
|
|
13
|
+
connect(): Promise<void>;
|
|
14
|
+
post(message: SandboxEnvelope): void;
|
|
15
|
+
subscribe(onMessage: (message: SandboxEnvelope, sender: MessageSender) => void): () => void;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { sandboxChannel, sandboxSender } from "../utils.js";
|
|
2
|
+
class SandboxInner {
|
|
3
|
+
constructor(name) {
|
|
4
|
+
this.name = name;
|
|
5
|
+
this.channel = sandboxChannel(name);
|
|
6
|
+
}
|
|
7
|
+
name;
|
|
8
|
+
channel;
|
|
9
|
+
unsubscribe;
|
|
10
|
+
connect() {
|
|
11
|
+
return Promise.resolve();
|
|
12
|
+
}
|
|
13
|
+
post(message) {
|
|
14
|
+
window.parent.postMessage(message, "*");
|
|
15
|
+
}
|
|
16
|
+
subscribe(onMessage) {
|
|
17
|
+
if (this.unsubscribe) {
|
|
18
|
+
return this.unsubscribe;
|
|
19
|
+
}
|
|
20
|
+
const listener = (event) => {
|
|
21
|
+
if (event.source !== window.parent) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const data = event.data;
|
|
25
|
+
if ((data == null ? void 0 : data.channel) !== this.channel || data.name !== this.name) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
onMessage(data, sandboxSender());
|
|
29
|
+
};
|
|
30
|
+
window.addEventListener("message", listener);
|
|
31
|
+
this.unsubscribe = () => {
|
|
32
|
+
window.removeEventListener("message", listener);
|
|
33
|
+
this.unsubscribe = void 0;
|
|
34
|
+
};
|
|
35
|
+
return this.unsubscribe;
|
|
36
|
+
}
|
|
37
|
+
dispose() {
|
|
38
|
+
var _a;
|
|
39
|
+
(_a = this.unsubscribe) == null ? void 0 : _a.call(this);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
SandboxInner as default
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=SandboxInner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/sandbox/ports/SandboxInner.ts"],"sourcesContent":["import {sandboxChannel, sandboxSender} from \"../utils\";\n\nimport type {SandboxEnvelope, SandboxPort} from \"@typing/sandbox\";\nimport type {MessageSender} from \"@typing/message\";\n\n/**\n * Sandbox-side `SandboxPort`: runs inside the iframe. There is no frame to create, so\n * `connect` resolves immediately (the ready handshake is posted by the sandbox builder);\n * `post` targets `window.parent`; `subscribe` listens for messages from the parent.\n */\nexport default class SandboxInner implements SandboxPort {\n private readonly channel: string;\n\n private unsubscribe?: () => void;\n\n constructor(private readonly name: string) {\n this.channel = sandboxChannel(name);\n }\n\n public connect(): Promise<void> {\n return Promise.resolve();\n }\n\n public post(message: SandboxEnvelope): void {\n // Opaque sandbox origin: no concrete targetOrigin is possible; the host trusts\n // messages by channel + name + requestId, never by origin.\n window.parent.postMessage(message, \"*\");\n }\n\n public subscribe(onMessage: (message: SandboxEnvelope, sender: MessageSender) => void): () => void {\n if (this.unsubscribe) {\n return this.unsubscribe;\n }\n\n const listener = (event: MessageEvent) => {\n if (event.source !== window.parent) {\n return;\n }\n\n const data = event.data as Partial<SandboxEnvelope>;\n\n if (data?.channel !== this.channel || data.name !== this.name) {\n return;\n }\n\n onMessage(data as SandboxEnvelope, sandboxSender());\n };\n\n window.addEventListener(\"message\", listener);\n\n this.unsubscribe = () => {\n window.removeEventListener(\"message\", listener);\n this.unsubscribe = undefined;\n };\n\n return this.unsubscribe;\n }\n\n public dispose(): void {\n this.unsubscribe?.();\n }\n}\n"],"mappings":"AAAA,SAAQ,gBAAgB,qBAAoB;AAU5C,MAAO,aAAkD;AAAA,EAKrD,YAA6B,MAAc;AAAd;AACzB,SAAK,UAAU,eAAe,IAAI;AAAA,EACtC;AAAA,EAF6B;AAAA,EAJZ;AAAA,EAET;AAAA,EAMD,UAAyB;AAC5B,WAAO,QAAQ,QAAQ;AAAA,EAC3B;AAAA,EAEO,KAAK,SAAgC;AAGxC,WAAO,OAAO,YAAY,SAAS,GAAG;AAAA,EAC1C;AAAA,EAEO,UAAU,WAAkF;AAC/F,QAAI,KAAK,aAAa;AAClB,aAAO,KAAK;AAAA,IAChB;AAEA,UAAM,WAAW,CAAC,UAAwB;AACtC,UAAI,MAAM,WAAW,OAAO,QAAQ;AAChC;AAAA,MACJ;AAEA,YAAM,OAAO,MAAM;AAEnB,WAAI,6BAAM,aAAY,KAAK,WAAW,KAAK,SAAS,KAAK,MAAM;AAC3D;AAAA,MACJ;AAEA,gBAAU,MAAyB,cAAc,CAAC;AAAA,IACtD;AAEA,WAAO,iBAAiB,WAAW,QAAQ;AAE3C,SAAK,cAAc,MAAM;AACrB,aAAO,oBAAoB,WAAW,QAAQ;AAC9C,WAAK,cAAc;AAAA,IACvB;AAEA,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,UAAgB;AA1D3B;AA2DQ,eAAK,gBAAL;AAAA,EACJ;AACJ;","names":[]}
|