bb-relay 0.0.32 → 0.0.33

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,8 +1,7 @@
1
1
  import { F as FileContent } from './FileContent-BWulmcoi.mjs';
2
2
 
3
3
  type Load = {
4
- styles: string;
5
- theme: "light" | "dark";
4
+ theme: string;
6
5
  languages: string[];
7
6
  };
8
7
 
@@ -11,7 +10,7 @@ type RelayEvent = {
11
10
  * Indicate change in theme
12
11
  */
13
12
  theme: {
14
- response: "dark" | "light";
13
+ response: string;
15
14
  };
16
15
  /**
17
16
  * Indicate that the iframe is loaded and ready to receive instructions
@@ -22,12 +21,6 @@ type RelayEvent = {
22
21
  load: {
23
22
  response: Load;
24
23
  };
25
- /**
26
- * The style of the editor
27
- */
28
- style: {
29
- response: string;
30
- };
31
24
  /**
32
25
  * The language of the editor
33
26
  */
@@ -55,8 +48,33 @@ type RelayEvent = {
55
48
  interface EventReturn<K extends keyof RelayEvent> {
56
49
  type: K;
57
50
  response: RelayEvent[K]["response"];
58
- responseId: string;
59
- source: "event";
60
51
  }
61
52
 
62
- export type { EventReturn as E, RelayEvent as R };
53
+ type RelayRequest = {
54
+ /**
55
+ * Updates the content of the current file
56
+ * Note, type is not stated, it would use the one stated in manifest
57
+ */
58
+ update: {
59
+ args: {
60
+ content: string;
61
+ };
62
+ response: {
63
+ error: string | null;
64
+ };
65
+ };
66
+ ping: {
67
+ args: unknown;
68
+ response: {
69
+ data: unknown | null;
70
+ };
71
+ };
72
+ };
73
+
74
+ interface RequestReturn<K extends keyof RelayRequest> {
75
+ type: K;
76
+ response: RelayRequest[K]["response"];
77
+ id: string;
78
+ }
79
+
80
+ export type { EventReturn as E, RelayEvent as R, RelayRequest as a, RequestReturn as b };
@@ -1,8 +1,7 @@
1
1
  import { F as FileContent } from './FileContent-BWulmcoi.js';
2
2
 
3
3
  type Load = {
4
- styles: string;
5
- theme: "light" | "dark";
4
+ theme: string;
6
5
  languages: string[];
7
6
  };
8
7
 
@@ -11,7 +10,7 @@ type RelayEvent = {
11
10
  * Indicate change in theme
12
11
  */
13
12
  theme: {
14
- response: "dark" | "light";
13
+ response: string;
15
14
  };
16
15
  /**
17
16
  * Indicate that the iframe is loaded and ready to receive instructions
@@ -22,12 +21,6 @@ type RelayEvent = {
22
21
  load: {
23
22
  response: Load;
24
23
  };
25
- /**
26
- * The style of the editor
27
- */
28
- style: {
29
- response: string;
30
- };
31
24
  /**
32
25
  * The language of the editor
33
26
  */
@@ -55,8 +48,33 @@ type RelayEvent = {
55
48
  interface EventReturn<K extends keyof RelayEvent> {
56
49
  type: K;
57
50
  response: RelayEvent[K]["response"];
58
- responseId: string;
59
- source: "event";
60
51
  }
61
52
 
62
- export type { EventReturn as E, RelayEvent as R };
53
+ type RelayRequest = {
54
+ /**
55
+ * Updates the content of the current file
56
+ * Note, type is not stated, it would use the one stated in manifest
57
+ */
58
+ update: {
59
+ args: {
60
+ content: string;
61
+ };
62
+ response: {
63
+ error: string | null;
64
+ };
65
+ };
66
+ ping: {
67
+ args: unknown;
68
+ response: {
69
+ data: unknown | null;
70
+ };
71
+ };
72
+ };
73
+
74
+ interface RequestReturn<K extends keyof RelayRequest> {
75
+ type: K;
76
+ response: RelayRequest[K]["response"];
77
+ id: string;
78
+ }
79
+
80
+ export type { EventReturn as E, RelayEvent as R, RelayRequest as a, RequestReturn as b };
package/dist/api.d.mts CHANGED
@@ -1,11 +1,17 @@
1
- import { R as RelayEvent } from './EventReturn-CGAZ-l1W.mjs';
2
- export { E as EventReturn } from './EventReturn-CGAZ-l1W.mjs';
1
+ import { R as RelayEvent, a as RelayRequest } from './RequestReturn-ClPSkigo.mjs';
2
+ export { E as EventReturn, b as RequestReturn } from './RequestReturn-ClPSkigo.mjs';
3
3
  import './FileContent-BWulmcoi.mjs';
4
4
 
5
5
  type EventParam<K extends keyof RelayEvent> = {
6
- id: string;
7
6
  type: K;
8
7
  source: "event";
9
8
  };
10
9
 
11
- export { type EventParam, RelayEvent };
10
+ type RequestParam<K extends keyof RelayRequest> = {
11
+ type: K;
12
+ source: "request";
13
+ id: string;
14
+ arg: RelayRequest[K]["args"];
15
+ };
16
+
17
+ export { type EventParam, RelayEvent, RelayRequest, type RequestParam };
package/dist/api.d.ts CHANGED
@@ -1,11 +1,17 @@
1
- import { R as RelayEvent } from './EventReturn-CXACStVQ.js';
2
- export { E as EventReturn } from './EventReturn-CXACStVQ.js';
1
+ import { R as RelayEvent, a as RelayRequest } from './RequestReturn-xCEiRgI1.js';
2
+ export { E as EventReturn, b as RequestReturn } from './RequestReturn-xCEiRgI1.js';
3
3
  import './FileContent-BWulmcoi.js';
4
4
 
5
5
  type EventParam<K extends keyof RelayEvent> = {
6
- id: string;
7
6
  type: K;
8
7
  source: "event";
9
8
  };
10
9
 
11
- export { type EventParam, RelayEvent };
10
+ type RequestParam<K extends keyof RelayRequest> = {
11
+ type: K;
12
+ source: "request";
13
+ id: string;
14
+ arg: RelayRequest[K]["args"];
15
+ };
16
+
17
+ export { type EventParam, RelayEvent, RelayRequest, type RequestParam };
package/dist/index.d.mts CHANGED
@@ -1,18 +1,9 @@
1
- import { R as RelayEvent, E as EventReturn } from './EventReturn-CGAZ-l1W.mjs';
2
1
  import { F as FileContent } from './FileContent-BWulmcoi.mjs';
3
2
  export { R as Result } from './Result-BLbZLEgX.mjs';
4
3
  import { P as Plugin } from './Plugin-Db_XUKx0.mjs';
4
+ import { R as RelayEvent, E as EventReturn, a as RelayRequest, b as RequestReturn } from './RequestReturn-ClPSkigo.mjs';
5
5
  import './Wrapper-DWhYVa7F.mjs';
6
6
 
7
- declare class Relay {
8
- private eventCallbacks;
9
- handleEvent<K extends keyof RelayEvent>(data: EventReturn<K>): void;
10
- init: () => void;
11
- constructor();
12
- subscribe<K extends keyof RelayEvent>(type: K, callback: (response: RelayEvent[K]["response"]) => void): () => void;
13
- destroy(): void;
14
- }
15
-
16
7
  /**
17
8
  * This is the function to inject styles to the iframe from the parent window
18
9
  * @param css the css styles from parent window
@@ -43,10 +34,7 @@ type Manifest = {
43
34
  author?: string;
44
35
  homepage?: string;
45
36
  repository?: string;
46
- theme?: {
47
- name: string;
48
- path: string;
49
- };
37
+ theme?: string;
50
38
  [key: string]: unknown;
51
39
  };
52
40
 
@@ -78,4 +66,11 @@ declare function validateUpload(manifest: Manifest, plugin: Plugin["doc"]): bool
78
66
  type BBEventKey = keyof RelayEvent;
79
67
  declare function postEventResponse<K extends BBEventKey>(window: Window, response: Omit<EventReturn<K>, "source" | "responseId">): void;
80
68
 
81
- export { type FileNode, type Manifest, type Zip, Relay as default, extractStyles, injectStyles, postEventResponse, validateManifest, validateUpload };
69
+ declare function subscribe<K extends keyof RelayEvent>(type: K, callback: (response: RelayEvent[K]["response"]) => void): void;
70
+
71
+ type BBRequestKey = keyof RelayRequest;
72
+ declare function postRequestResponse<K extends BBRequestKey>(window: Window, response: RequestReturn<K>): void;
73
+
74
+ declare function request<K extends keyof RelayRequest>(type: K, arg: RelayRequest[K]["args"], callback?: (response: RelayRequest[K]["response"]) => void): void;
75
+
76
+ export { type FileNode, type Manifest, type Zip, extractStyles, injectStyles, postEventResponse, postRequestResponse, request, subscribe, validateManifest, validateUpload };
package/dist/index.d.ts CHANGED
@@ -1,18 +1,9 @@
1
- import { R as RelayEvent, E as EventReturn } from './EventReturn-CXACStVQ.js';
2
1
  import { F as FileContent } from './FileContent-BWulmcoi.js';
3
2
  export { R as Result } from './Result-BLbZLEgX.js';
4
3
  import { P as Plugin } from './Plugin-t8StCIag.js';
4
+ import { R as RelayEvent, E as EventReturn, a as RelayRequest, b as RequestReturn } from './RequestReturn-xCEiRgI1.js';
5
5
  import './Wrapper-DWhYVa7F.js';
6
6
 
7
- declare class Relay {
8
- private eventCallbacks;
9
- handleEvent<K extends keyof RelayEvent>(data: EventReturn<K>): void;
10
- init: () => void;
11
- constructor();
12
- subscribe<K extends keyof RelayEvent>(type: K, callback: (response: RelayEvent[K]["response"]) => void): () => void;
13
- destroy(): void;
14
- }
15
-
16
7
  /**
17
8
  * This is the function to inject styles to the iframe from the parent window
18
9
  * @param css the css styles from parent window
@@ -43,10 +34,7 @@ type Manifest = {
43
34
  author?: string;
44
35
  homepage?: string;
45
36
  repository?: string;
46
- theme?: {
47
- name: string;
48
- path: string;
49
- };
37
+ theme?: string;
50
38
  [key: string]: unknown;
51
39
  };
52
40
 
@@ -78,4 +66,11 @@ declare function validateUpload(manifest: Manifest, plugin: Plugin["doc"]): bool
78
66
  type BBEventKey = keyof RelayEvent;
79
67
  declare function postEventResponse<K extends BBEventKey>(window: Window, response: Omit<EventReturn<K>, "source" | "responseId">): void;
80
68
 
81
- export { type FileNode, type Manifest, type Zip, Relay as default, extractStyles, injectStyles, postEventResponse, validateManifest, validateUpload };
69
+ declare function subscribe<K extends keyof RelayEvent>(type: K, callback: (response: RelayEvent[K]["response"]) => void): void;
70
+
71
+ type BBRequestKey = keyof RelayRequest;
72
+ declare function postRequestResponse<K extends BBRequestKey>(window: Window, response: RequestReturn<K>): void;
73
+
74
+ declare function request<K extends keyof RelayRequest>(type: K, arg: RelayRequest[K]["args"], callback?: (response: RelayRequest[K]["response"]) => void): void;
75
+
76
+ export { type FileNode, type Manifest, type Zip, extractStyles, injectStyles, postEventResponse, postRequestResponse, request, subscribe, validateManifest, validateUpload };
package/dist/index.js CHANGED
@@ -1,52 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/relay/registerEvent.ts
2
- function registerEvent(event) {
3
- if (!window) throw new Error("Window not found");
4
- if (window === window.parent) throw new Error("No parent window available");
5
- window.parent.postMessage({ ...event, source: "event" }, "*");
6
- }
7
-
8
- // src/relay/index.ts
9
- var Relay = class {
10
- constructor() {
11
- this.eventCallbacks = /* @__PURE__ */ new Map();
12
- this.init = () => {
13
- window.addEventListener("message", (event) => {
14
- this.handleEvent(event.data);
15
- });
16
- window.addEventListener("unload", () => {
17
- this.destroy();
18
- });
19
- };
20
- this.init();
21
- }
22
- handleEvent(data) {
23
- if (data.source !== "event") return;
24
- for (const [, { type, callback }] of this.eventCallbacks) {
25
- const { response } = data;
26
- if (type === data.type) {
27
- callback(response);
28
- return;
29
- }
30
- }
31
- }
32
- subscribe(type, callback) {
33
- const id = crypto.randomUUID();
34
- this.eventCallbacks.set(id, {
35
- type,
36
- callback
37
- });
38
- registerEvent({ type, id, source: "event" });
39
- return () => {
40
- this.eventCallbacks.delete(id);
41
- };
42
- }
43
- destroy() {
44
- this.eventCallbacks.clear();
45
- window.removeEventListener("message", this.init);
46
- }
47
- };
48
-
49
- // src/utils/inject-styles.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/utils/inject-styles.ts
50
2
  function injectStyles(css) {
51
3
  const style = document.createElement("style");
52
4
  style.textContent = css;
@@ -80,8 +32,6 @@ var validateManifest = (manifestContent) => {
80
32
  errors.push("Manifest permissions is missing");
81
33
  } else if (!Array.isArray(content.permissions)) {
82
34
  errors.push("Manifest permissions is not an array");
83
- } else if (content.permissions.length === 0) {
84
- errors.push("Manifest permissions is empty");
85
35
  }
86
36
  if (content.main) {
87
37
  if (!content.main.path) {
@@ -116,9 +66,7 @@ var validateManifest = (manifestContent) => {
116
66
  } else fileChecks.push(content.entry);
117
67
  }
118
68
  if (content.theme) {
119
- if (!content.theme.name) errors.push("No name for theme");
120
- if (!content.theme.path) errors.push("No css file path provided");
121
- else fileChecks.push(content.theme.path);
69
+ fileChecks.push(content.theme);
122
70
  }
123
71
  return {
124
72
  errors,
@@ -157,15 +105,59 @@ function validateUpload(manifest, plugin) {
157
105
  // src/relay/postEventResponse.ts
158
106
  function postEventResponse(window2, response) {
159
107
  const res = {
160
- ...response,
161
- source: "event",
162
- responseId: crypto.randomUUID()
108
+ ...response
109
+ };
110
+ window2.postMessage(res, "*");
111
+ }
112
+
113
+ // src/relay/registerEvent.ts
114
+ function registerEvent(event) {
115
+ if (!window) throw new Error("Window not found");
116
+ if (window === window.parent) throw new Error("No parent window available");
117
+ window.parent.postMessage({ ...event, source: "event" }, "*");
118
+ }
119
+
120
+ // src/relay/subscribe.ts
121
+ function subscribe(type, callback) {
122
+ registerEvent({ type, source: "event" });
123
+ window.addEventListener("message", (ev) => {
124
+ const data = ev.data;
125
+ const { response } = data;
126
+ if (type === data.type) {
127
+ callback(response);
128
+ }
129
+ });
130
+ }
131
+
132
+ // src/relay/postRequestResponse.ts
133
+ function postRequestResponse(window2, response) {
134
+ const res = {
135
+ ...response
163
136
  };
164
137
  window2.postMessage(res, "*");
165
138
  }
166
139
 
167
- // src/index.ts
168
- var index_default = Relay;
140
+ // src/relay/registerRequest.ts
141
+ function registerRequest(request2) {
142
+ if (!window) throw new Error("Window not found");
143
+ if (window === window.parent) throw new Error("No parent window available");
144
+ window.parent.postMessage({ ...request2, source: "request" }, "*");
145
+ }
146
+
147
+ // src/relay/request.ts
148
+ function request(type, arg, callback) {
149
+ const id = crypto.randomUUID();
150
+ registerRequest({ type, id, arg, source: "request" });
151
+ window.addEventListener("message", (ev) => {
152
+ const data = ev.data;
153
+ const { response } = data;
154
+ if (type === data.type && id === data.id) {
155
+ _optionalChain([callback, 'optionalCall', _ => _(response)]);
156
+ }
157
+ });
158
+ }
159
+
160
+
169
161
 
170
162
 
171
163
 
@@ -173,4 +165,4 @@ var index_default = Relay;
173
165
 
174
166
 
175
167
 
176
- exports.default = index_default; exports.extractStyles = extract_styles_default; exports.injectStyles = injectStyles; exports.postEventResponse = postEventResponse; exports.validateManifest = validate_manifest_default; exports.validateUpload = validateUpload;
168
+ exports.extractStyles = extract_styles_default; exports.injectStyles = injectStyles; exports.postEventResponse = postEventResponse; exports.postRequestResponse = postRequestResponse; exports.request = request; exports.subscribe = subscribe; exports.validateManifest = validate_manifest_default; exports.validateUpload = validateUpload;
package/dist/index.mjs CHANGED
@@ -1,51 +1,3 @@
1
- // src/relay/registerEvent.ts
2
- function registerEvent(event) {
3
- if (!window) throw new Error("Window not found");
4
- if (window === window.parent) throw new Error("No parent window available");
5
- window.parent.postMessage({ ...event, source: "event" }, "*");
6
- }
7
-
8
- // src/relay/index.ts
9
- var Relay = class {
10
- constructor() {
11
- this.eventCallbacks = /* @__PURE__ */ new Map();
12
- this.init = () => {
13
- window.addEventListener("message", (event) => {
14
- this.handleEvent(event.data);
15
- });
16
- window.addEventListener("unload", () => {
17
- this.destroy();
18
- });
19
- };
20
- this.init();
21
- }
22
- handleEvent(data) {
23
- if (data.source !== "event") return;
24
- for (const [, { type, callback }] of this.eventCallbacks) {
25
- const { response } = data;
26
- if (type === data.type) {
27
- callback(response);
28
- return;
29
- }
30
- }
31
- }
32
- subscribe(type, callback) {
33
- const id = crypto.randomUUID();
34
- this.eventCallbacks.set(id, {
35
- type,
36
- callback
37
- });
38
- registerEvent({ type, id, source: "event" });
39
- return () => {
40
- this.eventCallbacks.delete(id);
41
- };
42
- }
43
- destroy() {
44
- this.eventCallbacks.clear();
45
- window.removeEventListener("message", this.init);
46
- }
47
- };
48
-
49
1
  // src/utils/inject-styles.ts
50
2
  function injectStyles(css) {
51
3
  const style = document.createElement("style");
@@ -80,8 +32,6 @@ var validateManifest = (manifestContent) => {
80
32
  errors.push("Manifest permissions is missing");
81
33
  } else if (!Array.isArray(content.permissions)) {
82
34
  errors.push("Manifest permissions is not an array");
83
- } else if (content.permissions.length === 0) {
84
- errors.push("Manifest permissions is empty");
85
35
  }
86
36
  if (content.main) {
87
37
  if (!content.main.path) {
@@ -116,9 +66,7 @@ var validateManifest = (manifestContent) => {
116
66
  } else fileChecks.push(content.entry);
117
67
  }
118
68
  if (content.theme) {
119
- if (!content.theme.name) errors.push("No name for theme");
120
- if (!content.theme.path) errors.push("No css file path provided");
121
- else fileChecks.push(content.theme.path);
69
+ fileChecks.push(content.theme);
122
70
  }
123
71
  return {
124
72
  errors,
@@ -157,20 +105,64 @@ function validateUpload(manifest, plugin) {
157
105
  // src/relay/postEventResponse.ts
158
106
  function postEventResponse(window2, response) {
159
107
  const res = {
160
- ...response,
161
- source: "event",
162
- responseId: crypto.randomUUID()
108
+ ...response
109
+ };
110
+ window2.postMessage(res, "*");
111
+ }
112
+
113
+ // src/relay/registerEvent.ts
114
+ function registerEvent(event) {
115
+ if (!window) throw new Error("Window not found");
116
+ if (window === window.parent) throw new Error("No parent window available");
117
+ window.parent.postMessage({ ...event, source: "event" }, "*");
118
+ }
119
+
120
+ // src/relay/subscribe.ts
121
+ function subscribe(type, callback) {
122
+ registerEvent({ type, source: "event" });
123
+ window.addEventListener("message", (ev) => {
124
+ const data = ev.data;
125
+ const { response } = data;
126
+ if (type === data.type) {
127
+ callback(response);
128
+ }
129
+ });
130
+ }
131
+
132
+ // src/relay/postRequestResponse.ts
133
+ function postRequestResponse(window2, response) {
134
+ const res = {
135
+ ...response
163
136
  };
164
137
  window2.postMessage(res, "*");
165
138
  }
166
139
 
167
- // src/index.ts
168
- var index_default = Relay;
140
+ // src/relay/registerRequest.ts
141
+ function registerRequest(request2) {
142
+ if (!window) throw new Error("Window not found");
143
+ if (window === window.parent) throw new Error("No parent window available");
144
+ window.parent.postMessage({ ...request2, source: "request" }, "*");
145
+ }
146
+
147
+ // src/relay/request.ts
148
+ function request(type, arg, callback) {
149
+ const id = crypto.randomUUID();
150
+ registerRequest({ type, id, arg, source: "request" });
151
+ window.addEventListener("message", (ev) => {
152
+ const data = ev.data;
153
+ const { response } = data;
154
+ if (type === data.type && id === data.id) {
155
+ callback?.(response);
156
+ }
157
+ });
158
+ }
169
159
  export {
170
- index_default as default,
171
160
  extract_styles_default as extractStyles,
172
161
  injectStyles,
173
162
  postEventResponse,
163
+ postRequestResponse,
164
+ request,
165
+ subscribe,
174
166
  validate_manifest_default as validateManifest,
175
167
  validateUpload
176
168
  };
package/dist/plugin.d.mts CHANGED
@@ -46,7 +46,7 @@ interface InputInstruction extends BaseInstruction<"input"> {
46
46
  value: string;
47
47
  change?: string;
48
48
  label?: string;
49
- type: HTMLInputElement["type"];
49
+ type?: HTMLInputElement["type"];
50
50
  disabled?: boolean;
51
51
  }
52
52
 
@@ -233,7 +233,7 @@ declare abstract class Plugin<T extends Record<string, unknown>> {
233
233
  * return null
234
234
  * }
235
235
  */
236
- abstract renderSidebar(): ElementInstruction | null;
236
+ renderSidebar?(): ElementInstruction | null;
237
237
  private onSidebarLoad;
238
238
  /**
239
239
  * This will be like a dialog that will cover the main view.
@@ -266,6 +266,7 @@ declare abstract class Plugin<T extends Record<string, unknown>> {
266
266
  protected on(event: "file-created", callback: (filePath: string) => void): void;
267
267
  protected on(event: "file-changed", callback: (filePath: string) => void): void;
268
268
  protected on(event: "file-deleted", callback: (filePath: string) => void): void;
269
+ protected on(event: "ping", callback: (arg: unknown) => void): void;
269
270
  protected setState(param: SetState<T>): void;
270
271
  protected getState(): T;
271
272
  selectFile(filePath: string): void;
package/dist/plugin.d.ts CHANGED
@@ -46,7 +46,7 @@ interface InputInstruction extends BaseInstruction<"input"> {
46
46
  value: string;
47
47
  change?: string;
48
48
  label?: string;
49
- type: HTMLInputElement["type"];
49
+ type?: HTMLInputElement["type"];
50
50
  disabled?: boolean;
51
51
  }
52
52
 
@@ -233,7 +233,7 @@ declare abstract class Plugin<T extends Record<string, unknown>> {
233
233
  * return null
234
234
  * }
235
235
  */
236
- abstract renderSidebar(): ElementInstruction | null;
236
+ renderSidebar?(): ElementInstruction | null;
237
237
  private onSidebarLoad;
238
238
  /**
239
239
  * This will be like a dialog that will cover the main view.
@@ -266,6 +266,7 @@ declare abstract class Plugin<T extends Record<string, unknown>> {
266
266
  protected on(event: "file-created", callback: (filePath: string) => void): void;
267
267
  protected on(event: "file-changed", callback: (filePath: string) => void): void;
268
268
  protected on(event: "file-deleted", callback: (filePath: string) => void): void;
269
+ protected on(event: "ping", callback: (arg: unknown) => void): void;
269
270
  protected setState(param: SetState<T>): void;
270
271
  protected getState(): T;
271
272
  selectFile(filePath: string): void;
package/dist/plugin.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/lib/plugin/getPluginChannel.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/lib/plugin/getPluginChannel.ts
2
2
  var getPluginChannel = (event, pluginId) => {
3
3
  return `plugin:${pluginId}:${event}`;
4
4
  };
@@ -54,7 +54,7 @@ var Plugin = class {
54
54
  this.index = -1;
55
55
  this.eventIds.forEach((event) => this.off(event));
56
56
  this.eventIds = [];
57
- const sidebar = this.renderSidebar();
57
+ const sidebar = _optionalChain([this, 'access', _ => _.renderSidebar, 'optionalCall', _2 => _2()]) || null;
58
58
  if (sidebar) this.render("sidebar", sidebar);
59
59
  });
60
60
  this.onSidebarLoad();
@@ -90,7 +90,7 @@ var Plugin = class {
90
90
  onSidebarLoad() {
91
91
  this.index = -1;
92
92
  this.registerHandler("sidebar-load", () => {
93
- return this.renderSidebar();
93
+ return _optionalChain([this, 'access', _3 => _3.renderSidebar, 'optionalCall', _4 => _4()]) || null;
94
94
  });
95
95
  }
96
96
  // -----------------------------
package/dist/plugin.mjs CHANGED
@@ -54,7 +54,7 @@ var Plugin = class {
54
54
  this.index = -1;
55
55
  this.eventIds.forEach((event) => this.off(event));
56
56
  this.eventIds = [];
57
- const sidebar = this.renderSidebar();
57
+ const sidebar = this.renderSidebar?.() || null;
58
58
  if (sidebar) this.render("sidebar", sidebar);
59
59
  });
60
60
  this.onSidebarLoad();
@@ -90,7 +90,7 @@ var Plugin = class {
90
90
  onSidebarLoad() {
91
91
  this.index = -1;
92
92
  this.registerHandler("sidebar-load", () => {
93
- return this.renderSidebar();
93
+ return this.renderSidebar?.() || null;
94
94
  });
95
95
  }
96
96
  // -----------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bb-relay",
3
- "version": "0.0.32",
3
+ "version": "0.0.33",
4
4
  "description": "For managing bb-editor extension",
5
5
  "license": "ISC",
6
6
  "author": "Ade Adeola",
package/src/api.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  import RelayEvent from "./types/api/RelayEvent";
2
2
  import EventParam from "./types/api/EventParam";
3
3
  import EventReturn from "./types/api/EventReturn";
4
+ import RequestParam from "./types/api/RequestParam";
5
+ import RequestReturn from "./types/api/RequestReturn";
6
+ import { RelayRequest } from "./relay/registerRequest";
4
7
 
5
- export type { RelayEvent, EventReturn, EventParam };
8
+ export type {
9
+ RelayEvent,
10
+ EventReturn,
11
+ EventParam,
12
+ RequestParam,
13
+ RequestReturn,
14
+ RelayRequest,
15
+ };
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- import Relay from "./relay";
2
1
  import injectStyles from "./utils/inject-styles";
3
2
  import validateManifest from "./lib/validate-manifest";
4
3
  import { Manifest } from "./types/editor/Manifest";
@@ -7,12 +6,13 @@ import Result from "./types/editor/Result";
7
6
  import extractStyles from "./utils/extract-styles";
8
7
  import validateUpload from "./lib/validate-upload";
9
8
  import { postEventResponse } from "./relay/postEventResponse";
9
+ import subscribe from "./relay/subscribe";
10
+ import { postRequestResponse } from "./relay/postRequestResponse";
11
+ import request from "./relay/request";
10
12
 
11
- export default Relay;
12
-
13
- export { injectStyles, extractStyles };
13
+ export { injectStyles, extractStyles, subscribe, request };
14
14
  export { validateManifest, validateUpload };
15
- export { postEventResponse };
15
+ export { postEventResponse, postRequestResponse };
16
16
 
17
17
  export type { Result, FileNode, Zip };
18
18
 
@@ -5,6 +5,6 @@ export interface InputInstruction extends BaseInstruction<"input"> {
5
5
  value: string;
6
6
  change?: string;
7
7
  label?: string;
8
- type: HTMLInputElement["type"];
8
+ type?: HTMLInputElement["type"];
9
9
  disabled?: boolean;
10
10
  }
@@ -54,7 +54,8 @@ type EventSubs =
54
54
  | "file-selected"
55
55
  | "file-created"
56
56
  | "file-changed"
57
- | "file-deleted";
57
+ | "file-deleted"
58
+ | "ping";
58
59
 
59
60
  export type SetState<T extends Record<string, unknown>> =
60
61
  | Partial<T>
@@ -122,7 +123,7 @@ export abstract class Plugin<T extends Record<string, unknown>> {
122
123
  this.index = -1;
123
124
  this.eventIds.forEach((event) => this.off(event));
124
125
  this.eventIds = [];
125
- const sidebar = this.renderSidebar();
126
+ const sidebar = this.renderSidebar?.() || null;
126
127
  if (sidebar) this.render("sidebar", sidebar);
127
128
  });
128
129
 
@@ -212,12 +213,12 @@ export abstract class Plugin<T extends Record<string, unknown>> {
212
213
  * return null
213
214
  * }
214
215
  */
215
- abstract renderSidebar(): ElementInstruction | null;
216
+ renderSidebar?(): ElementInstruction | null;
216
217
 
217
218
  private onSidebarLoad(): void {
218
219
  this.index = -1;
219
220
  this.registerHandler("sidebar-load", () => {
220
- return this.renderSidebar();
221
+ return this.renderSidebar?.() || null;
221
222
  });
222
223
  }
223
224
  // -----------------------------
@@ -332,9 +333,12 @@ export abstract class Plugin<T extends Record<string, unknown>> {
332
333
  callback: (filePath: string) => void,
333
334
  ): void;
334
335
 
336
+ protected on(event: "ping", callback: (arg: unknown) => void): void;
337
+
335
338
  protected on(event: EventSubs, callback: (arg: any) => void): void {
336
339
  this.registerSubscription(event, callback);
337
340
  }
341
+
338
342
  // -----------------------------
339
343
  // Status Bar
340
344
  // -----------------------------
@@ -25,8 +25,6 @@ const validateManifest = (manifestContent: string) => {
25
25
  errors.push("Manifest permissions is missing");
26
26
  } else if (!Array.isArray(content.permissions)) {
27
27
  errors.push("Manifest permissions is not an array");
28
- } else if (content.permissions.length === 0) {
29
- errors.push("Manifest permissions is empty");
30
28
  }
31
29
 
32
30
  if (content.main) {
@@ -66,9 +64,7 @@ const validateManifest = (manifestContent: string) => {
66
64
  }
67
65
 
68
66
  if (content.theme) {
69
- if (!content.theme.name) errors.push("No name for theme");
70
- if (!content.theme.path) errors.push("No css file path provided");
71
- else fileChecks.push(content.theme.path);
67
+ fileChecks.push(content.theme);
72
68
  }
73
69
  return {
74
70
  errors,
@@ -8,8 +8,6 @@ export function postEventResponse<K extends BBEventKey>(
8
8
  ): void {
9
9
  const res: EventReturn<K> = {
10
10
  ...response,
11
- source: "event",
12
- responseId: crypto.randomUUID(),
13
11
  };
14
12
  window.postMessage(res, "*");
15
13
  }
@@ -0,0 +1,14 @@
1
+ import RequestReturn from "@/types/api/RequestReturn";
2
+ import { RelayRequest } from "./registerRequest";
3
+
4
+ type BBRequestKey = keyof RelayRequest;
5
+
6
+ export function postRequestResponse<K extends BBRequestKey>(
7
+ window: Window,
8
+ response: RequestReturn<K>,
9
+ ): void {
10
+ const res: RequestReturn<K> = {
11
+ ...response,
12
+ };
13
+ window.postMessage(res, "*");
14
+ }
@@ -0,0 +1,35 @@
1
+ import RequestParam from "@/types/api/RequestParam";
2
+
3
+ export type RelayRequest = {
4
+ /**
5
+ * Updates the content of the current file
6
+ * Note, type is not stated, it would use the one stated in manifest
7
+ */
8
+ update: {
9
+ args: {
10
+ content: string;
11
+ };
12
+ response: {
13
+ error: string | null;
14
+ };
15
+ };
16
+ ping: {
17
+ args: unknown;
18
+ response: {
19
+ data: unknown | null;
20
+ };
21
+ };
22
+ };
23
+
24
+ /**
25
+ * This will be used to send message (request) from the iframe to editor
26
+ * @param request the params that will be sent to the editor
27
+ */
28
+ export default function registerRequest<K extends keyof RelayRequest>(
29
+ request: RequestParam<K>,
30
+ ) {
31
+ if (!window) throw new Error("Window not found");
32
+ if (window === window.parent) throw new Error("No parent window available");
33
+
34
+ window.parent.postMessage({ ...request, source: "request" }, "*");
35
+ }
@@ -0,0 +1,19 @@
1
+ import registerRequest, { RelayRequest } from "./registerRequest";
2
+ import RequestReturn from "@/types/api/RequestReturn";
3
+
4
+ export default function request<K extends keyof RelayRequest>(
5
+ type: K,
6
+ arg: RelayRequest[K]["args"],
7
+ callback?: (response: RelayRequest[K]["response"]) => void,
8
+ ) {
9
+ const id = crypto.randomUUID();
10
+ registerRequest({ type, id, arg, source: "request" });
11
+ window.addEventListener("message", (ev: MessageEvent) => {
12
+ const data = ev.data as RequestReturn<K>;
13
+
14
+ const { response } = data as RequestReturn<K>;
15
+ if (type === data.type && id === data.id) {
16
+ callback?.(response);
17
+ }
18
+ });
19
+ }
@@ -0,0 +1,17 @@
1
+ import { EventReturn, RelayEvent } from "@/api";
2
+ import registerEvent from "./registerEvent";
3
+
4
+ export default function subscribe<K extends keyof RelayEvent>(
5
+ type: K,
6
+ callback: (response: RelayEvent[K]["response"]) => void,
7
+ ) {
8
+ registerEvent({ type: type, source: "event" });
9
+ window.addEventListener("message", (ev: MessageEvent) => {
10
+ const data = ev.data as EventReturn<K>;
11
+
12
+ const { response } = data as EventReturn<K>;
13
+ if (type === data.type) {
14
+ callback(response);
15
+ }
16
+ });
17
+ }
@@ -1,7 +1,6 @@
1
1
  import RelayEvent from "./RelayEvent";
2
2
 
3
3
  type EventParam<K extends keyof RelayEvent> = {
4
- id: string;
5
4
  type: K;
6
5
  source: "event";
7
6
  };
@@ -3,8 +3,6 @@ import RelayEvent from "./RelayEvent";
3
3
  interface EventReturn<K extends keyof RelayEvent> {
4
4
  type: K;
5
5
  response: RelayEvent[K]["response"];
6
- responseId: string;
7
- source: "event";
8
6
  }
9
7
 
10
8
  export default EventReturn;
@@ -6,7 +6,7 @@ type RelayEvent = {
6
6
  * Indicate change in theme
7
7
  */
8
8
  theme: {
9
- response: "dark" | "light";
9
+ response: string;
10
10
  };
11
11
  /**
12
12
  * Indicate that the iframe is loaded and ready to receive instructions
@@ -17,12 +17,6 @@ type RelayEvent = {
17
17
  load: {
18
18
  response: Load;
19
19
  };
20
- /**
21
- * The style of the editor
22
- */
23
- style: {
24
- response: string;
25
- };
26
20
  /**
27
21
  * The language of the editor
28
22
  */
@@ -0,0 +1,10 @@
1
+ import { RelayRequest } from "@/relay/registerRequest";
2
+
3
+ type RequestParam<K extends keyof RelayRequest> = {
4
+ type: K;
5
+ source: "request";
6
+ id: string;
7
+ arg: RelayRequest[K]["args"];
8
+ };
9
+
10
+ export default RequestParam;
@@ -0,0 +1,9 @@
1
+ import { RelayRequest } from "@/relay/registerRequest";
2
+
3
+ interface RequestReturn<K extends keyof RelayRequest> {
4
+ type: K;
5
+ response: RelayRequest[K]["response"];
6
+ id: string;
7
+ }
8
+
9
+ export default RequestReturn;
@@ -1,6 +1,5 @@
1
1
  type Load = {
2
- styles: string;
3
- theme: "light" | "dark";
2
+ theme: string;
4
3
  languages: string[];
5
4
  };
6
5
 
@@ -31,9 +31,6 @@ export type Manifest = {
31
31
  author?: string;
32
32
  homepage?: string;
33
33
  repository?: string;
34
- theme?: {
35
- name: string;
36
- path: string;
37
- };
34
+ theme?: string;
38
35
  [key: string]: unknown;
39
36
  };
@@ -1,61 +0,0 @@
1
- import RelayEvent from "../types/api/RelayEvent";
2
- import EventReturn from "../types/api/EventReturn";
3
- import registerEvent from "./registerEvent";
4
-
5
- export default class Relay {
6
- private eventCallbacks = new Map<
7
- string,
8
- {
9
- type: keyof RelayEvent;
10
- callback: <K extends keyof RelayEvent>(
11
- response: RelayEvent[K]["response"],
12
- ) => void;
13
- }
14
- >();
15
-
16
- handleEvent<K extends keyof RelayEvent>(data: EventReturn<K>) {
17
- if (data.source !== "event") return;
18
- for (const [, { type, callback }] of this.eventCallbacks) {
19
- const { response } = data as EventReturn<typeof data.type>;
20
- if (type === data.type) {
21
- callback(response);
22
- return;
23
- }
24
- }
25
- }
26
-
27
- init = () => {
28
- window.addEventListener("message", (event: MessageEvent) => {
29
- this.handleEvent(event.data as EventReturn<any>);
30
- });
31
-
32
- window.addEventListener("unload", () => {
33
- this.destroy();
34
- });
35
- };
36
-
37
- constructor() {
38
- this.init();
39
- }
40
-
41
- subscribe<K extends keyof RelayEvent>(
42
- type: K,
43
- callback: (response: RelayEvent[K]["response"]) => void,
44
- ) {
45
- const id = crypto.randomUUID();
46
- this.eventCallbacks.set(id, {
47
- type,
48
- callback: callback as (response: RelayEvent[K]["response"]) => void,
49
- });
50
- registerEvent({ type, id, source: "event" });
51
-
52
- return () => {
53
- this.eventCallbacks.delete(id);
54
- };
55
- }
56
-
57
- destroy() {
58
- this.eventCallbacks.clear();
59
- window.removeEventListener("message", this.init);
60
- }
61
- }