@nookuio/iframe 0.1.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.
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The path of the editor page which will be rendered in canvas
3
+ */
4
+ export declare const EDITOR_PAGE_PATH = "/__nooku/editor";
5
+ export declare const COMPONENT_PREVIEW_PAGE_PATH = "/__nooku/component-preview";
6
+ export declare const IFRAME_SOURCE_NAME = "nooku-frame";
7
+ export declare const EDITOR_SOURCE_NAME = "nooku-editor";
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.IFRAME_SOURCE_NAME = exports.EDITOR_SOURCE_NAME = exports.EDITOR_PAGE_PATH = exports.COMPONENT_PREVIEW_PAGE_PATH = void 0;
7
+ const EDITOR_PAGE_PATH = exports.EDITOR_PAGE_PATH = `/__nooku/editor`;
8
+ const COMPONENT_PREVIEW_PAGE_PATH = exports.COMPONENT_PREVIEW_PAGE_PATH = `/__nooku/component-preview`;
9
+ const IFRAME_SOURCE_NAME = exports.IFRAME_SOURCE_NAME = "nooku-frame";
10
+ const EDITOR_SOURCE_NAME = exports.EDITOR_SOURCE_NAME = "nooku-editor";
@@ -0,0 +1,4 @@
1
+ export const EDITOR_PAGE_PATH = `/__nooku/editor`;
2
+ export const COMPONENT_PREVIEW_PAGE_PATH = `/__nooku/component-preview`;
3
+ export const IFRAME_SOURCE_NAME = "nooku-frame";
4
+ export const EDITOR_SOURCE_NAME = "nooku-editor";
@@ -0,0 +1,54 @@
1
+ import type { ContextRequest, ContextResponse, EventListener } from './types';
2
+ type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
3
+ type ClientReturnBase<R, L, RE, LE> = {
4
+ [K in keyof R]: R[K] extends (...args: any[]) => any ? (...args: Parameters<R[K]>) => Promise<Awaited<ReturnType<R[K]>>> : R[K] extends any[] ? Promise<R[K]> : R[K] extends object ? ClientReturnBase<R[K], L, RE, LE> : Promise<R[K]>;
5
+ };
6
+ type ClientReturn<R, L, RE, LE> = ClientReturnBase<R, L, RE, LE> & {
7
+ $context: L;
8
+ on: <E extends keyof RE>(eventName: E, listener: (...args: ArgumentsType<RE[E]>) => void) => void;
9
+ off: <E extends keyof RE>(eventName: E, listener: (...args: ArgumentsType<RE[E]>) => void) => void;
10
+ emit: <E extends keyof LE>(eventName: E, ...args: ArgumentsType<LE[E]>) => void;
11
+ removeAllListeners: () => void;
12
+ };
13
+ interface ClientOptions {
14
+ /**
15
+ * Function to send requests to the main remote process
16
+ *
17
+ * Should return a ContextResponse
18
+ */
19
+ invoke: (request: ContextRequest) => Promise<ContextResponse>;
20
+ /**
21
+ * Function to handle incoming requests from the remote process
22
+ */
23
+ handle: (handler: (request: ContextRequest) => Promise<ContextResponse>) => void;
24
+ /**
25
+ * Function to emit events to the remote process
26
+ */
27
+ emit: (eventName: string, ...args: any[]) => void;
28
+ /**
29
+ * Function to subscribe to events from the remote process
30
+ */
31
+ subscribe: (eventName: string, listener: EventListener) => void;
32
+ /**
33
+ * Unsubscribe to events from the remote process
34
+ */
35
+ unsubscribe: (eventName: string, listener: EventListener) => void;
36
+ /**
37
+ * Remove all the listeners
38
+ */
39
+ removeAllListeners: () => void;
40
+ /**
41
+ * Custom function to serialize data
42
+ *
43
+ * by default it uses JSON.stringify
44
+ */
45
+ serialize?: (data: any) => any;
46
+ /**
47
+ * Custom function to deserialize data
48
+ *
49
+ * by default it uses JSON.parse
50
+ */
51
+ deserialize?: (data: any) => any;
52
+ }
53
+ export declare function createClient<R, L, RE, LE>(localCtx: L, options: ClientOptions): ClientReturn<R, L, RE, LE>;
54
+ export {};
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createClient = createClient;
7
+ var _lodash = _interopRequireDefault(require("lodash"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ function defaultSerialize(data) {
10
+ try {
11
+ return JSON.stringify(data);
12
+ } catch (error) {
13
+ return data;
14
+ }
15
+ }
16
+ function defaultDeserialize(data) {
17
+ try {
18
+ return JSON.parse(data);
19
+ } catch (error) {
20
+ return data;
21
+ }
22
+ }
23
+ function createClient(localCtx, options) {
24
+ const {
25
+ invoke,
26
+ handle,
27
+ subscribe,
28
+ removeAllListeners,
29
+ emit,
30
+ unsubscribe,
31
+ serialize = defaultSerialize,
32
+ deserialize = defaultDeserialize
33
+ } = options;
34
+ handle(async request => {
35
+ const value = _lodash.default.get(localCtx, request.key);
36
+ if (value === void 0) return {
37
+ type: "response",
38
+ id: request.id,
39
+ key: request.key,
40
+ result: void 0
41
+ };
42
+ const result = typeof value === "function" ? await value(...deserialize(request.args)) : value;
43
+ return {
44
+ type: "response",
45
+ id: request.id,
46
+ key: request.key,
47
+ result: serialize(result)
48
+ };
49
+ });
50
+ const proxyCache = /* @__PURE__ */new Map();
51
+ function createProxyForPath(path) {
52
+ const pathKey = path.join(".");
53
+ if (proxyCache.has(pathKey)) {
54
+ return proxyCache.get(pathKey);
55
+ }
56
+ const callHandler = async (...args) => {
57
+ const request = {
58
+ type: "request",
59
+ id: `${pathKey}-${Date.now()}-${Math.random()}`,
60
+ // More robust ID
61
+ key: pathKey,
62
+ args: serialize(args)
63
+ };
64
+ const response = await invoke(request);
65
+ return deserialize(response.result);
66
+ };
67
+ const proxy = new Proxy(callHandler, {
68
+ get(target, prop) {
69
+ if (prop === "then") {
70
+ const promise = target();
71
+ return promise.then.bind(promise);
72
+ }
73
+ if (prop === "catch" || prop === "finally") {
74
+ const promise = target();
75
+ return promise[prop].bind(promise);
76
+ }
77
+ return createProxyForPath([...path, prop]);
78
+ },
79
+ apply(target, thisArg, args) {
80
+ return target.apply(thisArg, args);
81
+ }
82
+ });
83
+ proxyCache.set(pathKey, proxy);
84
+ return proxy;
85
+ }
86
+ const rootProxy = new Proxy({}, {
87
+ get(_target, prop) {
88
+ if (prop === "$context") return localCtx;
89
+ if (prop === "on") return subscribe;
90
+ if (prop === "off") return unsubscribe;
91
+ if (prop === "emit") return emit;
92
+ if (prop === "removeAllListeners") return removeAllListeners;
93
+ if (typeof prop === "symbol") return void 0;
94
+ return createProxyForPath([prop]);
95
+ }
96
+ });
97
+ return rootProxy;
98
+ }
@@ -0,0 +1,95 @@
1
+ import _ from "lodash";
2
+ function defaultSerialize(data) {
3
+ try {
4
+ return JSON.stringify(data);
5
+ } catch (error) {
6
+ return data;
7
+ }
8
+ }
9
+ function defaultDeserialize(data) {
10
+ try {
11
+ return JSON.parse(data);
12
+ } catch (error) {
13
+ return data;
14
+ }
15
+ }
16
+ export function createClient(localCtx, options) {
17
+ const {
18
+ invoke,
19
+ handle,
20
+ subscribe,
21
+ removeAllListeners,
22
+ emit,
23
+ unsubscribe,
24
+ serialize = defaultSerialize,
25
+ deserialize = defaultDeserialize
26
+ } = options;
27
+ handle(async (request) => {
28
+ const value = _.get(localCtx, request.key);
29
+ if (value === void 0)
30
+ return {
31
+ type: "response",
32
+ id: request.id,
33
+ key: request.key,
34
+ result: void 0
35
+ };
36
+ const result = typeof value === "function" ? await value(...deserialize(request.args)) : value;
37
+ return {
38
+ type: "response",
39
+ id: request.id,
40
+ key: request.key,
41
+ result: serialize(result)
42
+ };
43
+ });
44
+ const proxyCache = /* @__PURE__ */ new Map();
45
+ function createProxyForPath(path) {
46
+ const pathKey = path.join(".");
47
+ if (proxyCache.has(pathKey)) {
48
+ return proxyCache.get(pathKey);
49
+ }
50
+ const callHandler = async (...args) => {
51
+ const request = {
52
+ type: "request",
53
+ id: `${pathKey}-${Date.now()}-${Math.random()}`,
54
+ // More robust ID
55
+ key: pathKey,
56
+ args: serialize(args)
57
+ };
58
+ const response = await invoke(request);
59
+ return deserialize(response.result);
60
+ };
61
+ const proxy = new Proxy(callHandler, {
62
+ get(target, prop) {
63
+ if (prop === "then") {
64
+ const promise = target();
65
+ return promise.then.bind(promise);
66
+ }
67
+ if (prop === "catch" || prop === "finally") {
68
+ const promise = target();
69
+ return promise[prop].bind(promise);
70
+ }
71
+ return createProxyForPath([...path, prop]);
72
+ },
73
+ apply(target, thisArg, args) {
74
+ return target.apply(thisArg, args);
75
+ }
76
+ });
77
+ proxyCache.set(pathKey, proxy);
78
+ return proxy;
79
+ }
80
+ const rootProxy = new Proxy(
81
+ {},
82
+ {
83
+ get(_target, prop) {
84
+ if (prop === "$context") return localCtx;
85
+ if (prop === "on") return subscribe;
86
+ if (prop === "off") return unsubscribe;
87
+ if (prop === "emit") return emit;
88
+ if (prop === "removeAllListeners") return removeAllListeners;
89
+ if (typeof prop === "symbol") return void 0;
90
+ return createProxyForPath([prop]);
91
+ }
92
+ }
93
+ );
94
+ return rootProxy;
95
+ }
@@ -0,0 +1,11 @@
1
+ import type { CoreIframeContext, CoreIframeEvents, EditorContext, EditorEvents } from './types';
2
+ /**
3
+ * This function should be called inside the editor
4
+ */
5
+ export declare function createIframeClient<IframeContext extends CoreIframeContext, IframeEvents extends CoreIframeEvents>(iframe: string | HTMLIFrameElement): { [K in keyof IframeContext]: IframeContext[K] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K]>) => Promise<Awaited<ReturnType<IframeContext[K]>>> : IframeContext[K] extends any[] ? Promise<IframeContext[K]> : IframeContext[K] extends object ? IframeContext[K] extends infer T ? { [K_1 in keyof T]: IframeContext[K][K_1] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1]>>> : IframeContext[K][K_1] extends any[] ? Promise<IframeContext[K][K_1]> : IframeContext[K][K_1] extends object ? IframeContext[K][K_1] extends infer T_1 ? { [K_2 in keyof T_1]: IframeContext[K][K_1][K_2] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2]>>> : IframeContext[K][K_1][K_2] extends any[] ? Promise<IframeContext[K][K_1][K_2]> : IframeContext[K][K_1][K_2] extends object ? IframeContext[K][K_1][K_2] extends infer T_2 ? { [K_3 in keyof T_2]: IframeContext[K][K_1][K_2][K_3] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2][K_3]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2][K_3]>>> : IframeContext[K][K_1][K_2][K_3] extends any[] ? Promise<IframeContext[K][K_1][K_2][K_3]> : IframeContext[K][K_1][K_2][K_3] extends object ? IframeContext[K][K_1][K_2][K_3] extends infer T_3 ? { [K_4 in keyof T_3]: IframeContext[K][K_1][K_2][K_3][K_4] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2][K_3][K_4]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2][K_3][K_4]>>> : IframeContext[K][K_1][K_2][K_3][K_4] extends any[] ? Promise<IframeContext[K][K_1][K_2][K_3][K_4]> : IframeContext[K][K_1][K_2][K_3][K_4] extends object ? IframeContext[K][K_1][K_2][K_3][K_4] extends infer T_4 ? { [K_5 in keyof T_4]: IframeContext[K][K_1][K_2][K_3][K_4][K_5] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2][K_3][K_4][K_5]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2][K_3][K_4][K_5]>>> : IframeContext[K][K_1][K_2][K_3][K_4][K_5] extends any[] ? Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5]> : IframeContext[K][K_1][K_2][K_3][K_4][K_5] extends object ? IframeContext[K][K_1][K_2][K_3][K_4][K_5] extends infer T_5 ? { [K_6 in keyof T_5]: IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6]>>> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6] extends any[] ? Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6]> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6] extends object ? IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6] extends infer T_6 ? { [K_7 in keyof T_6]: IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]>>> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends any[] ? Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends object ? IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends infer T_7 ? { [K_8 in keyof T_7]: IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]>>> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends any[] ? Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends object ? IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends infer T_8 ? { [K_9 in keyof T_8]: IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]>>> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends any[] ? Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends object ? IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends infer T_9 ? { [K_10 in keyof T_9]: IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10] extends (...args: any[]) => any ? (...args: Parameters<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]>) => Promise<Awaited<ReturnType<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]>>> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10] extends any[] ? Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]> : IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10] extends object ? /*elided*/ any : Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]>; } : never : Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]>; } : never : Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]>; } : never : Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]>; } : never : Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5][K_6]>; } : never : Promise<IframeContext[K][K_1][K_2][K_3][K_4][K_5]>; } : never : Promise<IframeContext[K][K_1][K_2][K_3][K_4]>; } : never : Promise<IframeContext[K][K_1][K_2][K_3]>; } : never : Promise<IframeContext[K][K_1][K_2]>; } : never : Promise<IframeContext[K][K_1]>; } : never : Promise<IframeContext[K]>; } & {
6
+ $context: EditorContext;
7
+ on: <E extends keyof IframeEvents>(eventName: E, listener: (...args: IframeEvents[E] extends infer T_10 ? T_10 extends IframeEvents[E] ? T_10 extends (...args: infer A) => any ? A : never : never : never) => void) => void;
8
+ off: <E extends keyof IframeEvents>(eventName: E, listener: (...args: IframeEvents[E] extends infer T_10 ? T_10 extends IframeEvents[E] ? T_10 extends (...args: infer A) => any ? A : never : never : never) => void) => void;
9
+ emit: <E extends never>(eventName: E, ...args: EditorEvents[E] extends infer T_10 ? T_10 extends EditorEvents[E] ? T_10 extends (...args: infer A) => any ? A : never : never : never) => void;
10
+ removeAllListeners: () => void;
11
+ };
package/dist/editor.js ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createIframeClient = createIframeClient;
7
+ var _constants = require("./constants");
8
+ var _createClient = require("./createClient");
9
+ var _telejson = require("telejson");
10
+ const listenersCollection = /* @__PURE__ */new Map();
11
+ function createIframeClient(iframe) {
12
+ let iframeElement;
13
+ function getIframe() {
14
+ if (!iframeElement) {
15
+ iframeElement = typeof iframe === "string" ? document.querySelector(`#${iframe}`) : iframe;
16
+ }
17
+ return iframeElement;
18
+ }
19
+ const client = (0, _createClient.createClient)({}, {
20
+ emit(eventName, ...args) {
21
+ const iframe2 = getIframe();
22
+ if (!iframe2) return;
23
+ iframe2.contentWindow?.postMessage({
24
+ source: _constants.EDITOR_SOURCE_NAME,
25
+ request: {
26
+ eventName,
27
+ args
28
+ }
29
+ }, "*");
30
+ },
31
+ handle(handler) {
32
+ window.addEventListener("message", async event => {
33
+ if (typeof event.data !== "object") return;
34
+ if (event.data.source !== _constants.IFRAME_SOURCE_NAME) return;
35
+ const iframe2 = getIframe();
36
+ if (!iframe2) return;
37
+ const response = await handler(event.data.request);
38
+ iframe2.contentWindow?.postMessage({
39
+ source: _constants.EDITOR_SOURCE_NAME,
40
+ response
41
+ }, "*");
42
+ });
43
+ },
44
+ async invoke(request) {
45
+ const iframe2 = getIframe();
46
+ if (!iframe2) return {
47
+ type: "response",
48
+ id: request.id,
49
+ key: request.key,
50
+ result: void 0
51
+ };
52
+ return new Promise((resolve, reject) => {
53
+ const timeout = setTimeout(() => {
54
+ window.removeEventListener("message", messageHandler);
55
+ reject(new Error("Request timed out"));
56
+ }, 5e3);
57
+ function messageHandler(event) {
58
+ if (typeof event.data !== "object") return;
59
+ if (event.data.source !== _constants.IFRAME_SOURCE_NAME || !event.data.response) return;
60
+ if (event.data.response.id !== request.id) return;
61
+ clearTimeout(timeout);
62
+ window.removeEventListener("message", messageHandler);
63
+ resolve(event.data.response);
64
+ }
65
+ iframe2.contentWindow?.postMessage({
66
+ source: _constants.IFRAME_SOURCE_NAME,
67
+ request
68
+ }, "*");
69
+ window.addEventListener("message", messageHandler);
70
+ });
71
+ },
72
+ subscribe(eventName, listener) {
73
+ const currentEventListenersCollection = listenersCollection.get(eventName);
74
+ if (!currentEventListenersCollection) {
75
+ listenersCollection.set(eventName, [listener]);
76
+ return;
77
+ }
78
+ currentEventListenersCollection.push(listener);
79
+ },
80
+ unsubscribe(eventName, listener) {
81
+ const index = listenersCollection.get(eventName)?.indexOf(listener);
82
+ if (index === -1 || index === void 0) return;
83
+ listenersCollection.get(eventName)?.splice(index, 1);
84
+ },
85
+ removeAllListeners() {
86
+ listenersCollection.clear();
87
+ },
88
+ deserialize: v => (0, _telejson.parse)(v),
89
+ serialize: v => (0, _telejson.stringify)(v, {
90
+ maxDepth: Infinity
91
+ })
92
+ });
93
+ window.addEventListener("message", event => {
94
+ if (typeof event.data !== "object") return;
95
+ if (event.data.source !== _constants.IFRAME_SOURCE_NAME || !event.data.request) return;
96
+ const currentEventListeners = listenersCollection.get(event.data.request.eventName);
97
+ if (!currentEventListeners?.length) return;
98
+ currentEventListeners.forEach(listener => listener(...event.data.request.args));
99
+ });
100
+ return client;
101
+ }
@@ -0,0 +1,85 @@
1
+ import { EDITOR_SOURCE_NAME, IFRAME_SOURCE_NAME } from "./constants.mjs";
2
+ import { createClient } from "./createClient.mjs";
3
+ import { stringify, parse } from "telejson";
4
+ const listenersCollection = /* @__PURE__ */ new Map();
5
+ export function createIframeClient(iframe) {
6
+ let iframeElement;
7
+ function getIframe() {
8
+ if (!iframeElement) {
9
+ iframeElement = typeof iframe === "string" ? document.querySelector(`#${iframe}`) : iframe;
10
+ }
11
+ return iframeElement;
12
+ }
13
+ const client = createClient(
14
+ {},
15
+ {
16
+ emit(eventName, ...args) {
17
+ const iframe2 = getIframe();
18
+ if (!iframe2) return;
19
+ iframe2.contentWindow?.postMessage({ source: EDITOR_SOURCE_NAME, request: { eventName, args } }, "*");
20
+ },
21
+ handle(handler) {
22
+ window.addEventListener("message", async (event) => {
23
+ if (typeof event.data !== "object") return;
24
+ if (event.data.source !== IFRAME_SOURCE_NAME) return;
25
+ const iframe2 = getIframe();
26
+ if (!iframe2) return;
27
+ const response = await handler(event.data.request);
28
+ iframe2.contentWindow?.postMessage({ source: EDITOR_SOURCE_NAME, response }, "*");
29
+ });
30
+ },
31
+ async invoke(request) {
32
+ const iframe2 = getIframe();
33
+ if (!iframe2)
34
+ return {
35
+ type: "response",
36
+ id: request.id,
37
+ key: request.key,
38
+ result: void 0
39
+ };
40
+ return new Promise((resolve, reject) => {
41
+ const timeout = setTimeout(() => {
42
+ window.removeEventListener("message", messageHandler);
43
+ reject(new Error("Request timed out"));
44
+ }, 5e3);
45
+ function messageHandler(event) {
46
+ if (typeof event.data !== "object") return;
47
+ if (event.data.source !== IFRAME_SOURCE_NAME || !event.data.response) return;
48
+ if (event.data.response.id !== request.id) return;
49
+ clearTimeout(timeout);
50
+ window.removeEventListener("message", messageHandler);
51
+ resolve(event.data.response);
52
+ }
53
+ iframe2.contentWindow?.postMessage({ source: IFRAME_SOURCE_NAME, request }, "*");
54
+ window.addEventListener("message", messageHandler);
55
+ });
56
+ },
57
+ subscribe(eventName, listener) {
58
+ const currentEventListenersCollection = listenersCollection.get(eventName);
59
+ if (!currentEventListenersCollection) {
60
+ listenersCollection.set(eventName, [listener]);
61
+ return;
62
+ }
63
+ currentEventListenersCollection.push(listener);
64
+ },
65
+ unsubscribe(eventName, listener) {
66
+ const index = listenersCollection.get(eventName)?.indexOf(listener);
67
+ if (index === -1 || index === void 0) return;
68
+ listenersCollection.get(eventName)?.splice(index, 1);
69
+ },
70
+ removeAllListeners() {
71
+ listenersCollection.clear();
72
+ },
73
+ deserialize: (v) => parse(v),
74
+ serialize: (v) => stringify(v, { maxDepth: Infinity })
75
+ }
76
+ );
77
+ window.addEventListener("message", (event) => {
78
+ if (typeof event.data !== "object") return;
79
+ if (event.data.source !== IFRAME_SOURCE_NAME || !event.data.request) return;
80
+ const currentEventListeners = listenersCollection.get(event.data.request.eventName);
81
+ if (!currentEventListeners?.length) return;
82
+ currentEventListeners.forEach((listener) => listener(...event.data.request.args));
83
+ });
84
+ return client;
85
+ }
@@ -0,0 +1,11 @@
1
+ import type { CoreIframeContext, CoreIframeEvents, EditorEvents } from './types';
2
+ /**
3
+ * This function should be called inside the iframe
4
+ */
5
+ export declare function createIframeClient<IframeContext extends CoreIframeContext, IframeEvents extends CoreIframeEvents>(local: Exclude<IframeContext, CoreIframeContext>): {} & {
6
+ $context: CoreIframeContext;
7
+ on: <E extends never>(eventName: E, listener: (...args: EditorEvents[E] extends infer T ? T extends EditorEvents[E] ? T extends (...args: infer A) => any ? A : never : never : never) => void) => void;
8
+ off: <E extends never>(eventName: E, listener: (...args: EditorEvents[E] extends infer T ? T extends EditorEvents[E] ? T extends (...args: infer A) => any ? A : never : never : never) => void) => void;
9
+ emit: <E extends keyof CoreIframeEvents>(eventName: E, ...args: CoreIframeEvents[E] extends infer T ? T extends CoreIframeEvents[E] ? T extends (...args: infer A) => any ? A : never : never : never) => void;
10
+ removeAllListeners: () => void;
11
+ };
package/dist/iframe.js ADDED
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createIframeClient = createIframeClient;
7
+ var _constants = require("./constants");
8
+ var _createClient = require("./createClient");
9
+ var _telejson = require("telejson");
10
+ const listenersCollection = /* @__PURE__ */new Map();
11
+ function getSelector(path, id) {
12
+ return `[data-node-id="${id}"][data-node-path="${path}"]`;
13
+ }
14
+ function getElementStyles(selector, withPadding) {
15
+ const elements = document.querySelectorAll(selector);
16
+ if (!elements?.length) return;
17
+ const styles = Array.from(elements).map(element => {
18
+ const clientRect = element.getBoundingClientRect();
19
+ const position = {
20
+ width: clientRect.width,
21
+ height: clientRect.height,
22
+ top: clientRect.top,
23
+ left: clientRect.left
24
+ };
25
+ if (!withPadding) return position;
26
+ const computedStyle = window.getComputedStyle(element) ?? {};
27
+ return {
28
+ ...position,
29
+ padding: {
30
+ top: computedStyle.paddingTop,
31
+ right: computedStyle.paddingRight,
32
+ bottom: computedStyle.paddingBottom,
33
+ left: computedStyle.paddingLeft
34
+ }
35
+ };
36
+ });
37
+ if (!styles?.length) return;
38
+ return styles.length === 1 ? styles[0] : styles;
39
+ }
40
+ function createIframeClient(local) {
41
+ const client = (0, _createClient.createClient)({
42
+ document: window.document,
43
+ async editText({
44
+ path,
45
+ id
46
+ }) {
47
+ if (!path || id === void 0) return;
48
+ const selector = getSelector(path, id);
49
+ const element = document.querySelector(selector);
50
+ if (!element) return;
51
+ element.style.outline = "none";
52
+ element.setAttribute("spellcheck", "false");
53
+ element.setAttribute("contenteditable", "true");
54
+ const blurEvtHandler = event => {
55
+ const elm = event.target;
56
+ if (!elm) return;
57
+ const content = elm.innerText;
58
+ element.removeAttribute("contenteditable");
59
+ client.emit("text-update", {
60
+ path,
61
+ id,
62
+ content
63
+ });
64
+ element.removeEventListener("blur", blurEvtHandler);
65
+ element.removeEventListener("keydown", keyDownEvtHandler);
66
+ element.blur();
67
+ };
68
+ const keyDownEvtHandler = event => {
69
+ if (event.key === "Enter") {
70
+ event.stopPropagation();
71
+ event.preventDefault();
72
+ blurEvtHandler(event);
73
+ }
74
+ };
75
+ element.addEventListener("keydown", keyDownEvtHandler);
76
+ element.addEventListener("blur", blurEvtHandler);
77
+ element.focus();
78
+ },
79
+ async getHoveredElement({
80
+ path,
81
+ id,
82
+ x,
83
+ y
84
+ }) {
85
+ if (!path) return;
86
+ if (x !== void 0 && y !== void 0) {
87
+ let element = document.elementFromPoint(x, y);
88
+ if (!element) return;
89
+ let elementPath = element.getAttribute("data-node-path");
90
+ if (elementPath !== path) {
91
+ if (!element.parentElement) return;
92
+ while (element.parentElement && path !== path) {
93
+ element = element.parentElement;
94
+ elementPath = element.getAttribute("data-node-path");
95
+ }
96
+ }
97
+ const elementId = element.getAttribute("data-node-id");
98
+ if (!elementId) return;
99
+ const selector = getSelector(path, elementId);
100
+ const styles = getElementStyles(selector, false);
101
+ if (!styles) return;
102
+ return {
103
+ id: elementId,
104
+ path,
105
+ data: styles
106
+ };
107
+ } else {
108
+ const selector = getSelector(path, id);
109
+ const styles = getElementStyles(selector, false);
110
+ if (!styles) return;
111
+ return {
112
+ id,
113
+ path,
114
+ data: styles
115
+ };
116
+ }
117
+ },
118
+ async getPageHeight() {
119
+ const height = document.body.scrollHeight > 0 ? document.body.scrollHeight : document.documentElement.scrollHeight;
120
+ return height;
121
+ },
122
+ async getSelectedElement({
123
+ path,
124
+ id
125
+ }) {
126
+ const selector = getSelector(path, id);
127
+ const styles = getElementStyles(selector, true);
128
+ if (!styles) return;
129
+ return {
130
+ path,
131
+ id,
132
+ data: styles
133
+ };
134
+ },
135
+ toggleTheme(theme) {
136
+ if (theme === "dark") {
137
+ document.documentElement.classList.remove("light");
138
+ document.documentElement.classList.add("dark");
139
+ } else {
140
+ document.documentElement.classList.remove("dark");
141
+ document.documentElement.classList.add("light");
142
+ }
143
+ }
144
+ }, {
145
+ emit(eventName, ...args) {
146
+ window.parent.postMessage({
147
+ source: _constants.IFRAME_SOURCE_NAME,
148
+ request: {
149
+ eventName,
150
+ args
151
+ }
152
+ }, "*");
153
+ },
154
+ handle(handler) {
155
+ window.addEventListener("message", async event => {
156
+ if (typeof event.data !== "object") return;
157
+ if (event.data.source !== _constants.EDITOR_SOURCE_NAME) return;
158
+ const response = await handler(event.data.request);
159
+ window.parent.postMessage({
160
+ source: _constants.IFRAME_SOURCE_NAME,
161
+ response
162
+ }, "*");
163
+ });
164
+ },
165
+ invoke(request) {
166
+ return new Promise((resolve, reject) => {
167
+ const timeout = setTimeout(() => {
168
+ window.removeEventListener("message", messageHandler);
169
+ reject(new Error("Request timed out"));
170
+ }, 5e3);
171
+ function messageHandler(event) {
172
+ if (typeof event.data !== "object") return;
173
+ if (event.data.source !== _constants.EDITOR_SOURCE_NAME || !event.data.response) return;
174
+ if (event.data.response.id !== request.id) return;
175
+ clearTimeout(timeout);
176
+ window.removeEventListener("message", messageHandler);
177
+ resolve(event.data.response);
178
+ }
179
+ window.parent.postMessage({
180
+ source: _constants.IFRAME_SOURCE_NAME,
181
+ request
182
+ }, "*");
183
+ window.addEventListener("message", messageHandler);
184
+ });
185
+ },
186
+ subscribe(eventName, listener) {
187
+ const currentEventListeners = listenersCollection.get(eventName);
188
+ if (!currentEventListeners) {
189
+ listenersCollection.set(eventName, [listener]);
190
+ return;
191
+ }
192
+ currentEventListeners.push(listener);
193
+ },
194
+ unsubscribe(eventName, listener) {
195
+ const index = listenersCollection.get(eventName)?.indexOf(listener);
196
+ if (index === -1 || index === void 0) return;
197
+ listenersCollection.get(eventName)?.splice(index, 1);
198
+ },
199
+ removeAllListeners() {
200
+ listenersCollection.clear();
201
+ },
202
+ deserialize: v => (0, _telejson.parse)(v),
203
+ serialize: v => (0, _telejson.stringify)(v, {
204
+ maxDepth: Infinity
205
+ })
206
+ });
207
+ window.addEventListener("message", event => {
208
+ if (typeof event.data !== "object") return;
209
+ if (event.data.source !== _constants.EDITOR_SOURCE_NAME || !event.data.request) return;
210
+ const currentEventListeners = listenersCollection.get(event.data.request.eventName);
211
+ if (!currentEventListeners?.length) return;
212
+ currentEventListeners.forEach(listener => listener(...event.data.request.args));
213
+ });
214
+ console.log = (...args) => {
215
+ client.emit("console", "log", args);
216
+ };
217
+ console.warn = (...args) => {};
218
+ console.error = (...args) => {
219
+ client.emit("console", "error", args);
220
+ };
221
+ console.info = (...args) => {
222
+ client.emit("console", "info", args);
223
+ };
224
+ window.addEventListener("resize", async () => client.emit("resize", await client.$context.getPageHeight()));
225
+ const mutationObserver = new MutationObserver(async () => client.emit("resize", await client.$context.getPageHeight()));
226
+ mutationObserver.observe(document.body, {
227
+ childList: true,
228
+ // observe direct children additions/removals
229
+ subtree: true,
230
+ // observe all descendants
231
+ attributes: true,
232
+ // observe attribute changes (like style, class)
233
+ characterData: true
234
+ // observe text changes
235
+ });
236
+ client.emit("ready");
237
+ return client;
238
+ }
@@ -0,0 +1,209 @@
1
+ import { EDITOR_SOURCE_NAME, IFRAME_SOURCE_NAME } from "./constants.mjs";
2
+ import { createClient } from "./createClient.mjs";
3
+ import { stringify, parse } from "telejson";
4
+ const listenersCollection = /* @__PURE__ */ new Map();
5
+ function getSelector(path, id) {
6
+ return `[data-node-id="${id}"][data-node-path="${path}"]`;
7
+ }
8
+ function getElementStyles(selector, withPadding) {
9
+ const elements = document.querySelectorAll(selector);
10
+ if (!elements?.length) return;
11
+ const styles = Array.from(elements).map((element) => {
12
+ const clientRect = element.getBoundingClientRect();
13
+ const position = {
14
+ width: clientRect.width,
15
+ height: clientRect.height,
16
+ top: clientRect.top,
17
+ left: clientRect.left
18
+ };
19
+ if (!withPadding) return position;
20
+ const computedStyle = window.getComputedStyle(element) ?? {};
21
+ return {
22
+ ...position,
23
+ padding: {
24
+ top: computedStyle.paddingTop,
25
+ right: computedStyle.paddingRight,
26
+ bottom: computedStyle.paddingBottom,
27
+ left: computedStyle.paddingLeft
28
+ }
29
+ };
30
+ });
31
+ if (!styles?.length) return;
32
+ return styles.length === 1 ? styles[0] : styles;
33
+ }
34
+ export function createIframeClient(local) {
35
+ const client = createClient(
36
+ {
37
+ document: window.document,
38
+ async editText({ path, id }) {
39
+ if (!path || id === void 0) return;
40
+ const selector = getSelector(path, id);
41
+ const element = document.querySelector(selector);
42
+ if (!element) return;
43
+ element.style.outline = "none";
44
+ element.setAttribute("spellcheck", "false");
45
+ element.setAttribute("contenteditable", "true");
46
+ const blurEvtHandler = (event) => {
47
+ const elm = event.target;
48
+ if (!elm) return;
49
+ const content = elm.innerText;
50
+ element.removeAttribute("contenteditable");
51
+ client.emit("text-update", { path, id, content });
52
+ element.removeEventListener("blur", blurEvtHandler);
53
+ element.removeEventListener("keydown", keyDownEvtHandler);
54
+ element.blur();
55
+ };
56
+ const keyDownEvtHandler = (event) => {
57
+ if (event.key === "Enter") {
58
+ event.stopPropagation();
59
+ event.preventDefault();
60
+ blurEvtHandler(event);
61
+ }
62
+ };
63
+ element.addEventListener("keydown", keyDownEvtHandler);
64
+ element.addEventListener("blur", blurEvtHandler);
65
+ element.focus();
66
+ },
67
+ async getHoveredElement({ path, id, x, y }) {
68
+ if (!path) return;
69
+ if (x !== void 0 && y !== void 0) {
70
+ let element = document.elementFromPoint(x, y);
71
+ if (!element) return;
72
+ let elementPath = element.getAttribute("data-node-path");
73
+ if (elementPath !== path) {
74
+ if (!element.parentElement) return;
75
+ while (element.parentElement && path !== path) {
76
+ element = element.parentElement;
77
+ elementPath = element.getAttribute("data-node-path");
78
+ }
79
+ }
80
+ const elementId = element.getAttribute("data-node-id");
81
+ if (!elementId) return;
82
+ const selector = getSelector(path, elementId);
83
+ const styles = getElementStyles(selector, false);
84
+ if (!styles) return;
85
+ return {
86
+ id: elementId,
87
+ path,
88
+ data: styles
89
+ };
90
+ } else {
91
+ const selector = getSelector(path, id);
92
+ const styles = getElementStyles(selector, false);
93
+ if (!styles) return;
94
+ return {
95
+ id,
96
+ path,
97
+ data: styles
98
+ };
99
+ }
100
+ },
101
+ async getPageHeight() {
102
+ const height = document.body.scrollHeight > 0 ? document.body.scrollHeight : document.documentElement.scrollHeight;
103
+ return height;
104
+ },
105
+ async getSelectedElement({ path, id }) {
106
+ const selector = getSelector(path, id);
107
+ const styles = getElementStyles(selector, true);
108
+ if (!styles) return;
109
+ return {
110
+ path,
111
+ id,
112
+ data: styles
113
+ };
114
+ },
115
+ toggleTheme(theme) {
116
+ if (theme === "dark") {
117
+ document.documentElement.classList.remove("light");
118
+ document.documentElement.classList.add("dark");
119
+ } else {
120
+ document.documentElement.classList.remove("dark");
121
+ document.documentElement.classList.add("light");
122
+ }
123
+ }
124
+ },
125
+ {
126
+ emit(eventName, ...args) {
127
+ window.parent.postMessage({ source: IFRAME_SOURCE_NAME, request: { eventName, args } }, "*");
128
+ },
129
+ handle(handler) {
130
+ window.addEventListener("message", async (event) => {
131
+ if (typeof event.data !== "object") return;
132
+ if (event.data.source !== EDITOR_SOURCE_NAME) return;
133
+ const response = await handler(event.data.request);
134
+ window.parent.postMessage({ source: IFRAME_SOURCE_NAME, response }, "*");
135
+ });
136
+ },
137
+ invoke(request) {
138
+ return new Promise((resolve, reject) => {
139
+ const timeout = setTimeout(() => {
140
+ window.removeEventListener("message", messageHandler);
141
+ reject(new Error("Request timed out"));
142
+ }, 5e3);
143
+ function messageHandler(event) {
144
+ if (typeof event.data !== "object") return;
145
+ if (event.data.source !== EDITOR_SOURCE_NAME || !event.data.response) return;
146
+ if (event.data.response.id !== request.id) return;
147
+ clearTimeout(timeout);
148
+ window.removeEventListener("message", messageHandler);
149
+ resolve(event.data.response);
150
+ }
151
+ window.parent.postMessage({ source: IFRAME_SOURCE_NAME, request }, "*");
152
+ window.addEventListener("message", messageHandler);
153
+ });
154
+ },
155
+ subscribe(eventName, listener) {
156
+ const currentEventListeners = listenersCollection.get(eventName);
157
+ if (!currentEventListeners) {
158
+ listenersCollection.set(eventName, [listener]);
159
+ return;
160
+ }
161
+ currentEventListeners.push(listener);
162
+ },
163
+ unsubscribe(eventName, listener) {
164
+ const index = listenersCollection.get(eventName)?.indexOf(listener);
165
+ if (index === -1 || index === void 0) return;
166
+ listenersCollection.get(eventName)?.splice(index, 1);
167
+ },
168
+ removeAllListeners() {
169
+ listenersCollection.clear();
170
+ },
171
+ deserialize: (v) => parse(v),
172
+ serialize: (v) => stringify(v, { maxDepth: Infinity })
173
+ }
174
+ );
175
+ window.addEventListener("message", (event) => {
176
+ if (typeof event.data !== "object") return;
177
+ if (event.data.source !== EDITOR_SOURCE_NAME || !event.data.request) return;
178
+ const currentEventListeners = listenersCollection.get(event.data.request.eventName);
179
+ if (!currentEventListeners?.length) return;
180
+ currentEventListeners.forEach((listener) => listener(...event.data.request.args));
181
+ });
182
+ console.log = (...args) => {
183
+ client.emit("console", "log", args);
184
+ };
185
+ console.warn = (...args) => {
186
+ };
187
+ console.error = (...args) => {
188
+ client.emit("console", "error", args);
189
+ };
190
+ console.info = (...args) => {
191
+ client.emit("console", "info", args);
192
+ };
193
+ window.addEventListener("resize", async () => client.emit("resize", await client.$context.getPageHeight()));
194
+ const mutationObserver = new MutationObserver(
195
+ async () => client.emit("resize", await client.$context.getPageHeight())
196
+ );
197
+ mutationObserver.observe(document.body, {
198
+ childList: true,
199
+ // observe direct children additions/removals
200
+ subtree: true,
201
+ // observe all descendants
202
+ attributes: true,
203
+ // observe attribute changes (like style, class)
204
+ characterData: true
205
+ // observe text changes
206
+ });
207
+ client.emit("ready");
208
+ return client;
209
+ }
@@ -0,0 +1,3 @@
1
+ export * from './createClient';
2
+ export * from './constants';
3
+ export * from './types';
package/dist/index.js ADDED
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _createClient = require("./createClient");
7
+ Object.keys(_createClient).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _createClient[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _createClient[key];
14
+ }
15
+ });
16
+ });
17
+ var _constants = require("./constants");
18
+ Object.keys(_constants).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _constants[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _constants[key];
25
+ }
26
+ });
27
+ });
28
+ var _types = require("./types");
29
+ Object.keys(_types).forEach(function (key) {
30
+ if (key === "default" || key === "__esModule") return;
31
+ if (key in exports && exports[key] === _types[key]) return;
32
+ Object.defineProperty(exports, key, {
33
+ enumerable: true,
34
+ get: function () {
35
+ return _types[key];
36
+ }
37
+ });
38
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./createClient.mjs";
2
+ export * from "./constants.mjs";
3
+ export * from "./types.mjs";
@@ -0,0 +1,95 @@
1
+ export interface EventRequest {
2
+ eventName: string;
3
+ args: any[];
4
+ }
5
+ export type EventListener = (...args: any[]) => void;
6
+ export interface ContextRequest {
7
+ type: 'request';
8
+ id: string;
9
+ key: string;
10
+ args: any[];
11
+ }
12
+ export interface ContextResponse {
13
+ type: 'response';
14
+ id: string;
15
+ key: string;
16
+ result: any;
17
+ }
18
+ export interface CoreIframeContext {
19
+ toggleTheme: (theme: 'dark' | 'light') => void;
20
+ getHoveredElement: (options: {
21
+ path: string;
22
+ id?: string;
23
+ x?: number;
24
+ y?: number;
25
+ }) => Promise<{
26
+ id: string;
27
+ path: string;
28
+ data: ElementPosition | ElementPosition[];
29
+ } | undefined>;
30
+ getSelectedElement: (options: {
31
+ path: string;
32
+ id: string;
33
+ }) => Promise<{
34
+ id: string;
35
+ path: string;
36
+ data: ElementStyles | ElementStyles[];
37
+ } | undefined>;
38
+ getPageHeight: () => Promise<number>;
39
+ editText: (options: {
40
+ path: string;
41
+ id: string;
42
+ }) => void;
43
+ document: Document;
44
+ }
45
+ export interface CoreIframeEvents {
46
+ ready: () => void;
47
+ 'route-change': (to: string) => void;
48
+ resize: (height: number) => void;
49
+ 'text-update': (options: {
50
+ path: string;
51
+ id: string;
52
+ content: string;
53
+ }) => void;
54
+ console: (type: 'log' | 'error' | 'info' | 'warn', message: any[]) => void;
55
+ }
56
+ export interface IframeContext extends CoreIframeContext {
57
+ navigateTo: (to: string) => void;
58
+ getValue: (opts: {
59
+ code: string;
60
+ path?: string;
61
+ onTemplateContext?: boolean;
62
+ context?: Record<string, any>;
63
+ }) => any;
64
+ getInstanceData: (path: string /** filepath path of the component */) => Record<string, any>;
65
+ runCode: (opts: {
66
+ path?: string;
67
+ code: string;
68
+ onTemplateContext?: boolean;
69
+ context?: Record<string, any>;
70
+ }) => any;
71
+ updatePreview?: (options: {
72
+ path: string;
73
+ code: string;
74
+ }) => void;
75
+ }
76
+ export interface IframeEvents extends CoreIframeEvents {
77
+ }
78
+ export interface EditorContext {
79
+ }
80
+ export interface EditorEvents {
81
+ }
82
+ export interface ElementPosition {
83
+ top: number;
84
+ left: number;
85
+ width: number;
86
+ height: number;
87
+ }
88
+ export interface ElementStyles extends ElementPosition {
89
+ padding: {
90
+ top: string;
91
+ right: string;
92
+ bottom: string;
93
+ left: string;
94
+ };
95
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";
package/dist/types.mjs ADDED
File without changes
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@nookuio/iframe",
3
+ "description": "",
4
+ "version": "0.1.0",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "import": "./dist/index.mjs",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./iframe": {
14
+ "require": "./dist/iframe.js",
15
+ "import": "./dist/iframe.mjs",
16
+ "types": "./dist/iframe.d.ts"
17
+ },
18
+ "./editor": {
19
+ "require": "./dist/editor.js",
20
+ "import": "./dist/editor.mjs",
21
+ "types": "./dist/editor.d.ts"
22
+ },
23
+ "./types": {
24
+ "require": "./dist/types.js",
25
+ "import": "./dist/types.mjs",
26
+ "types": "./dist/types.d.ts"
27
+ }
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "dependencies": {
33
+ "telejson": "^7.2.0"
34
+ },
35
+ "devDependencies": {},
36
+ "keywords": [],
37
+ "author": "",
38
+ "license": "ISC",
39
+ "scripts": {
40
+ "build": "unbuild"
41
+ }
42
+ }