webext-messenger 0.22.0-4 → 0.22.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.
@@ -1,5 +1,5 @@
1
1
  import { __getTabData } from "./thisTarget.js";
2
- import { Method } from "./types.js";
2
+ import { type Method } from "./types.js";
3
3
  declare global {
4
4
  interface MessengerMethods {
5
5
  __getTabData: typeof __getTabData;
@@ -1,4 +1,4 @@
1
1
  export * from "./receiver.js";
2
2
  export * from "./sender.js";
3
3
  export * from "./types.js";
4
- export { getThisTarget } from "./thisTarget.js";
4
+ export { getThisFrame, getTopLevelFrame } from "./thisTarget.js";
@@ -2,6 +2,6 @@
2
2
  export * from "./receiver.js";
3
3
  export * from "./sender.js";
4
4
  export * from "./types.js";
5
- export { getThisTarget } from "./thisTarget.js";
5
+ export { getThisFrame, getTopLevelFrame } from "./thisTarget.js";
6
6
  import { initPrivateApi } from "./thisTarget.js";
7
7
  initPrivateApi();
@@ -1,3 +1,3 @@
1
- import { Message } from "./types.js";
1
+ import { type Message } from "./types.js";
2
2
  export declare function isMessengerMessage(message: unknown): message is Message;
3
3
  export declare function registerMethods(methods: Partial<MessengerMethods>): void;
@@ -1,5 +1,5 @@
1
- import { PublicMethod, PublicMethodWithTarget, Options, Target, PageTarget } from "./types.js";
2
- import { SetReturnType } from "type-fest";
1
+ import { type PublicMethod, type PublicMethodWithTarget, type Options, type Target, type PageTarget } from "./types.js";
2
+ import { type SetReturnType } from "type-fest";
3
3
  export declare const errorTargetClosedEarly = "The target was closed before receiving a response";
4
4
  export declare const errorTabDoesntExist = "The tab doesn't exist";
5
5
  declare function messenger<Type extends keyof MessengerMethods, Method extends MessengerMethods[Type]>(type: Type, options: {
@@ -1,5 +1,5 @@
1
- import { JsonObject } from "type-fest";
2
- declare type ErrorObject = {
1
+ import { type JsonObject } from "type-fest";
2
+ type ErrorObject = {
3
3
  name?: string;
4
4
  stack?: string;
5
5
  message?: string;
@@ -1,5 +1,6 @@
1
- import { AnyTarget, KnownTarget, Message, MessengerMeta, Sender } from "./types.js";
1
+ import { type AnyTarget, type TopLevelFrame, type Message, type MessengerMeta, type Sender, type FrameTarget } from "./types.js";
2
2
  export declare function getActionForMessage(from: Sender, message: Message): "respond" | "forward" | "ignore";
3
3
  export declare function __getTabData(this: MessengerMeta): AnyTarget;
4
- export declare function getThisTarget(): Promise<KnownTarget>;
4
+ export declare function getThisFrame(): Promise<FrameTarget>;
5
+ export declare function getTopLevelFrame(): Promise<TopLevelFrame>;
5
6
  export declare function initPrivateApi(): void;
@@ -29,16 +29,17 @@ const thisTarget = isBackground()
29
29
  ? { page: "background" }
30
30
  : {
31
31
  get page() {
32
- return location.pathname + location.search;
32
+ // Extension pages have relative URLs to simplify comparison
33
+ const origin = location.protocol.startsWith("http")
34
+ ? location.origin
35
+ : "";
36
+ // Don't use the hash
37
+ return origin + location.pathname + location.search;
33
38
  },
34
39
  };
35
40
  let tabDataStatus =
36
41
  // The background page doesn't have a tab
37
- isBackground() ||
38
- // Content scripts don't use named targets yet
39
- isContentScript()
40
- ? "not-needed"
41
- : "needed";
42
+ isBackground() ? "not-needed" : "needed";
42
43
  function compareTargets(to, thisTarget) {
43
44
  for (const [key, value] of Object.entries(to)) {
44
45
  if (thisTarget[key] === value) {
@@ -112,9 +113,21 @@ const storeTabData = once(async () => {
112
113
  export function __getTabData() {
113
114
  return { tabId: this.trace[0]?.tab?.id, frameId: this.trace[0]?.frameId };
114
115
  }
115
- export async function getThisTarget() {
116
+ export async function getThisFrame() {
116
117
  await storeTabData(); // It should already have been called by we still need to await it
117
- return thisTarget;
118
+ const { tabId, frameId } = thisTarget;
119
+ if (typeof tabId !== "number" || typeof frameId !== "number") {
120
+ throw new TypeError("This target is not in a frame");
121
+ }
122
+ // Rebuild object to return exactly these two properties and nothing more
123
+ return { tabId, frameId };
124
+ }
125
+ export async function getTopLevelFrame() {
126
+ const { tabId } = await getThisFrame();
127
+ return {
128
+ tabId,
129
+ frameId: 0,
130
+ };
118
131
  }
119
132
  export function initPrivateApi() {
120
133
  if (isExtensionContext()) {
@@ -1,30 +1,35 @@
1
- import { Runtime } from "webextension-polyfill";
2
- import { Asyncify, ValueOf } from "type-fest";
3
- import { ErrorObject } from "serialize-error";
1
+ import { type Runtime } from "webextension-polyfill";
2
+ import { type Asyncify, type ValueOf } from "type-fest";
3
+ import { type ErrorObject } from "serialize-error";
4
+ /**
5
+ * @file Target types are a bit overlapping. That's because some are "request" targets
6
+ * and some are "known" targets. The difference is that you could "request" `{tabId: 1}`, but you "know" that a specific target is exactly `{tabId: 1, frameId: 5}`
7
+ * TODO: Cleanup, clarify, deduplicate Target types
8
+ */
4
9
  declare global {
5
10
  interface MessengerMethods {
6
11
  _: Method;
7
12
  }
8
13
  }
9
- declare type WithTarget<Method> = Method extends (...args: infer PreviousArguments) => infer TReturnValue ? (target: Target | PageTarget, ...args: PreviousArguments) => TReturnValue : never;
10
- declare type ActuallyOmitThisParameter<T> = T extends (...args: infer A) => infer R ? (...args: A) => R : T;
14
+ type WithTarget<Method> = Method extends (...args: infer PreviousArguments) => infer TReturnValue ? (target: Target | PageTarget, ...args: PreviousArguments) => TReturnValue : never;
15
+ type ActuallyOmitThisParameter<T> = T extends (...args: infer A) => infer R ? (...args: A) => R : T;
11
16
  /** Removes the `this` type and ensure it's always Promised */
12
- export declare type PublicMethod<Method extends ValueOf<MessengerMethods>> = Asyncify<ActuallyOmitThisParameter<Method>>;
13
- export declare type PublicMethodWithTarget<Method extends ValueOf<MessengerMethods>> = WithTarget<PublicMethod<Method>>;
17
+ export type PublicMethod<Method extends ValueOf<MessengerMethods>> = Asyncify<ActuallyOmitThisParameter<Method>>;
18
+ export type PublicMethodWithTarget<Method extends ValueOf<MessengerMethods>> = WithTarget<PublicMethod<Method>>;
14
19
  export interface MessengerMeta {
15
20
  trace: Sender[];
16
21
  }
17
- declare type RawMessengerResponse = {
22
+ type RawMessengerResponse = {
18
23
  value: unknown;
19
24
  } | {
20
25
  error: ErrorObject;
21
26
  };
22
- export declare type MessengerResponse = RawMessengerResponse & {
27
+ export type MessengerResponse = RawMessengerResponse & {
23
28
  /** Guarantees that the message was handled by this library */
24
29
  __webextMessenger: true;
25
30
  };
26
- declare type Arguments = any[];
27
- export declare type Method = (this: MessengerMeta, ...args: Arguments) => Promise<unknown>;
31
+ type Arguments = any[];
32
+ export type Method = (this: MessengerMeta, ...args: Arguments) => Promise<unknown>;
28
33
  export interface Options {
29
34
  /**
30
35
  * "Notifications" won't await the response, return values, attempt retries, nor throw errors
@@ -33,17 +38,17 @@ export interface Options {
33
38
  isNotification?: boolean;
34
39
  trace?: Sender[];
35
40
  }
36
- export declare type Message<LocalArguments extends Arguments = Arguments> = {
41
+ export type Message<LocalArguments extends Arguments = Arguments> = {
37
42
  type: keyof MessengerMethods;
38
43
  args: LocalArguments;
39
44
  target: Target | PageTarget;
40
45
  /** If the message is being sent to an intermediary receiver, also set the options */
41
46
  options?: Options;
42
47
  };
43
- export declare type Sender = Runtime.MessageSender & {
48
+ export type Sender = Runtime.MessageSender & {
44
49
  origin?: string;
45
50
  };
46
- export declare type MessengerMessage = Message & {
51
+ export type MessengerMessage = Message & {
47
52
  /** Guarantees that a message is meant to be handled by this library */
48
53
  __webextMessenger: true;
49
54
  };
@@ -52,6 +57,14 @@ export interface AnyTarget {
52
57
  frameId?: number;
53
58
  page?: string;
54
59
  }
60
+ export interface TopLevelFrame {
61
+ tabId: number;
62
+ frameId: 0;
63
+ }
64
+ export interface FrameTarget {
65
+ tabId: number;
66
+ frameId: number;
67
+ }
55
68
  export interface KnownTarget {
56
69
  tabId?: number;
57
70
  frameId?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webext-messenger",
3
- "version": "0.22.0-4",
3
+ "version": "0.22.0",
4
4
  "description": "Browser Extension component messaging framework",
5
5
  "keywords": [],
6
6
  "repository": "pixiebrix/webext-messenger",
@@ -21,25 +21,19 @@
21
21
  "dependencies": {
22
22
  "p-retry": "^5.1.1",
23
23
  "serialize-error": "^11.0.0",
24
- "type-fest": "^2.13.0",
24
+ "type-fest": "^3.2.0",
25
25
  "webext-detect-page": "^4.0.1",
26
26
  "webext-tools": "^1.1.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@parcel/config-webextension": "^2.6.0",
29
+ "@parcel/config-webextension": "^2.8.0",
30
30
  "@sindresorhus/tsconfig": "^3.0.1",
31
- "@types/chrome": "^0.0.188",
31
+ "@types/chrome": "^0.0.203",
32
32
  "@types/tape": "^4.13.2",
33
33
  "@types/webextension-polyfill": "^0.9.0",
34
- "@typescript-eslint/eslint-plugin": "^5.27.0",
35
- "@typescript-eslint/parser": "^5.27.0",
36
34
  "buffer": "^6.0.3",
37
- "eslint": "^8.17.0",
38
- "eslint-config-prettier": "^8.5.0",
39
- "eslint-config-xo": "^0.41.0",
40
- "eslint-config-xo-typescript": "^0.51.1",
41
- "eslint-plugin-import": "^2.26.0",
42
- "eslint-plugin-unicorn": "^42.0.0",
35
+ "eslint": "^8.28.0",
36
+ "eslint-config-pixiebrix": "^0.20.0",
43
37
  "events": "^3.3.0",
44
38
  "npm-run-all": "^4.1.5",
45
39
  "parcel": "^2.6.0",
@@ -47,9 +41,9 @@
47
41
  "process": "^0.11.10",
48
42
  "stream-browserify": "^3.0.0",
49
43
  "tape": "^5.5.3",
50
- "typescript": "^4.7.3",
44
+ "typescript": "^4.9.3",
51
45
  "webext-content-scripts": "^1.0.2",
52
- "webextension-polyfill": "^0.9.0"
46
+ "webextension-polyfill": "^0.10.0"
53
47
  },
54
48
  "alias": {
55
49
  "./this-stuff-is-just-for-local-parcel-tests": "https://github.com/parcel-bundler/parcel/issues/4936",