@web-applets/sdk 0.1.5 → 0.2.0-alpha.9

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,32 +0,0 @@
1
- import { ActionParams, AppletDataEvent, AppletLoadEvent, AppletReadyEvent, JSONSchema, AppletManifest, AppletAction, AppletMessageRelay } from './shared';
2
- export type ActionHandler<T extends ActionParams> = (params: T) => void | Promise<void>;
3
- export type ActionHandlerDict = {
4
- [key: string]: ActionHandler<any>;
5
- };
6
- export declare class AppletContext extends EventTarget {
7
- #private;
8
- messageRelay: AppletMessageRelay;
9
- actionHandlers: ActionHandlerDict;
10
- manifest: AppletManifest;
11
- constructor();
12
- connect(): void;
13
- initialize(): Promise<void>;
14
- createResizeObserver(): void;
15
- attachListeners(): void;
16
- setActionHandler<T = ActionParams>(actionId: string, handler: ActionHandler<T>): void;
17
- defineAction<T = ActionParams>(actionId: string, definition: ActionDefinition<T>): void;
18
- set actions(actions: AppletAction[]);
19
- get actions(): AppletAction[];
20
- set data(data: any);
21
- get data(): any;
22
- setData(data: any): Promise<void>;
23
- onload(event: AppletLoadEvent): Promise<void> | void;
24
- onready(event: AppletReadyEvent): void;
25
- ondata(event: AppletDataEvent): void;
26
- }
27
- interface ActionDefinition<T> extends Omit<AppletAction, 'id'> {
28
- parameters?: JSONSchema;
29
- handler?: ActionHandler<T>;
30
- }
31
- export declare function getContext(): AppletContext;
32
- export {};
@@ -1,138 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
7
- if (kind === "m") throw new TypeError("Private method is not writable");
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
- };
12
- var _AppletContext_actions, _AppletContext_data;
13
- import { AppletMessage, AppletDataEvent, AppletLoadEvent, AppletReadyEvent, AppletActionsMessage, AppletReadyMessage, AppletMessageRelay, } from './shared';
14
- export class AppletContext extends EventTarget {
15
- constructor() {
16
- super();
17
- this.actionHandlers = {};
18
- _AppletContext_actions.set(this, {});
19
- _AppletContext_data.set(this, void 0);
20
- this.connect();
21
- }
22
- connect() {
23
- this.messageRelay = new AppletMessageRelay(window.parent);
24
- // When document loads/if it's loaded, call the initialize function
25
- if (document.readyState === 'complete' ||
26
- document.readyState === 'interactive') {
27
- // Document has loaded already.
28
- // Timeout added so if the caller defines the onload function, it will exist by now
29
- setTimeout(this.initialize.bind(this), 1);
30
- }
31
- else {
32
- // Document not yet loaded, we'll add an event listener to call when it does
33
- window.addEventListener('DOMContentLoaded', this.initialize.bind(this));
34
- }
35
- this.attachListeners();
36
- }
37
- async initialize() {
38
- const manifestLinkElem = document.querySelector('link[rel="manifest"]');
39
- if (!manifestLinkElem)
40
- return;
41
- try {
42
- const manifestRequest = await fetch(manifestLinkElem.href);
43
- const manifest = await manifestRequest.json();
44
- this.manifest = manifest;
45
- this.actions = manifest.actions ?? [];
46
- }
47
- catch (e) {
48
- return;
49
- }
50
- // Call the onload function
51
- const loadEvent = new AppletLoadEvent();
52
- this.dispatchEvent(loadEvent);
53
- if (typeof this.onload === 'function')
54
- await this.onload(loadEvent);
55
- // Tell the host we're ready
56
- this.messageRelay.send(new AppletReadyMessage());
57
- // Emit a local ready event
58
- const readyEvent = new AppletReadyEvent();
59
- this.dispatchEvent(readyEvent);
60
- if (typeof this.onready === 'function')
61
- this.onready(readyEvent);
62
- this.createResizeObserver();
63
- }
64
- createResizeObserver() {
65
- const resizeObserver = new ResizeObserver((entries) => {
66
- for (let entry of entries) {
67
- const message = new AppletMessage('resize', {
68
- dimensions: {
69
- width: entry.contentRect.width,
70
- height: entry.contentRect.height,
71
- },
72
- });
73
- this.messageRelay.send(message);
74
- }
75
- });
76
- resizeObserver.observe(document.querySelector('html'));
77
- }
78
- attachListeners() {
79
- this.messageRelay.on('init', (message) => {
80
- this.manifest = message.manifest;
81
- this.actions = this.manifest?.actions || [];
82
- });
83
- this.messageRelay.on('data', (message) => {
84
- this.setData(message.data);
85
- });
86
- this.messageRelay.on('action', async (message) => {
87
- if (Object.keys(this.actionHandlers).includes(message.actionId)) {
88
- await this.actionHandlers[message.actionId](message.params);
89
- }
90
- });
91
- }
92
- setActionHandler(actionId, handler) {
93
- this.actionHandlers[actionId] = handler;
94
- }
95
- defineAction(actionId, definition) {
96
- const { handler, ...properties } = definition;
97
- this.actions = [
98
- ...this.actions,
99
- {
100
- id: actionId,
101
- ...properties,
102
- },
103
- ];
104
- this.setActionHandler(actionId, handler);
105
- }
106
- set actions(actions) {
107
- if (!actions)
108
- return;
109
- for (let action of actions) {
110
- __classPrivateFieldGet(this, _AppletContext_actions, "f")[action.id] = action;
111
- }
112
- this.messageRelay.send(new AppletActionsMessage({ actions: this.actions }));
113
- }
114
- get actions() {
115
- return Object.values(__classPrivateFieldGet(this, _AppletContext_actions, "f"));
116
- }
117
- set data(data) {
118
- this.setData(data);
119
- }
120
- get data() {
121
- return __classPrivateFieldGet(this, _AppletContext_data, "f");
122
- }
123
- async setData(data) {
124
- const dataMessage = new AppletMessage('data', { data });
125
- await this.messageRelay.send(dataMessage);
126
- __classPrivateFieldSet(this, _AppletContext_data, data, "f");
127
- const dataEvent = new AppletDataEvent({ data });
128
- this.dispatchEvent(dataEvent);
129
- this.ondata(dataEvent);
130
- }
131
- onload(event) { }
132
- onready(event) { }
133
- ondata(event) { }
134
- }
135
- _AppletContext_actions = new WeakMap(), _AppletContext_data = new WeakMap();
136
- export function getContext() {
137
- return new AppletContext();
138
- }
@@ -1,124 +0,0 @@
1
- export interface AppletManifest {
2
- name?: string;
3
- short_name?: string;
4
- icons: ManifestIcon[];
5
- description?: string;
6
- display?: string;
7
- start_url?: string;
8
- unsafe?: boolean;
9
- actions?: AppletAction[];
10
- }
11
- export interface ManifestIcon {
12
- src: string;
13
- purpose?: string;
14
- sizes?: string;
15
- type?: string;
16
- }
17
- export interface AppletAction {
18
- id: string;
19
- name?: string;
20
- description?: string;
21
- parameters?: JSONSchema;
22
- }
23
- export interface JSONSchema {
24
- type: 'object' | 'string' | 'number' | 'integer' | 'array' | 'boolean' | 'null';
25
- description?: string;
26
- properties?: {
27
- [key: string]: JSONSchema;
28
- };
29
- required?: string[];
30
- additionalProperties?: boolean;
31
- }
32
- export type ActionParams = Record<string, any>;
33
- export declare function loadManifest(pageUrl: string): Promise<AppletManifest>;
34
- interface SendMessageOptions {
35
- resolves: boolean;
36
- }
37
- export declare class AppletMessageRelay {
38
- target: Window;
39
- constructor(target: Window);
40
- send(message: AppletMessage, options?: SendMessageOptions): Promise<AppletMessage>;
41
- on(messageType: AppletMessageType, callback: AppletMessageCallback): Promise<void>;
42
- }
43
- export declare class AppletMessage {
44
- type: AppletMessageType;
45
- id: string;
46
- timeStamp: number;
47
- [key: string]: any;
48
- constructor(type: AppletMessageType, values?: {
49
- [key: string]: any;
50
- });
51
- toJson(): {
52
- [k: string]: any;
53
- };
54
- }
55
- export declare class AppletResolveMessage extends AppletMessage {
56
- messageId: string;
57
- constructor({ id }: {
58
- id: string;
59
- });
60
- }
61
- export declare class AppletActionsMessage extends AppletMessage {
62
- actions: AppletAction[];
63
- constructor({ actions }: {
64
- actions: AppletAction[];
65
- });
66
- }
67
- export declare class AppletDataMessage<T = any> extends AppletMessage {
68
- data: T;
69
- constructor({ data }: {
70
- data: T;
71
- });
72
- }
73
- export declare class AppletReadyMessage extends AppletMessage {
74
- constructor();
75
- }
76
- export declare class AppletResizeMessage extends AppletMessage {
77
- dimensions: {
78
- height: number;
79
- width: number;
80
- };
81
- constructor({ dimensions, }: {
82
- dimensions: AppletResizeMessage['dimensions'];
83
- });
84
- }
85
- interface AppletActionMessageOptions {
86
- actionId: string;
87
- params: any;
88
- }
89
- export declare class AppletActionMessage extends AppletMessage {
90
- actionId: string;
91
- params: any;
92
- constructor({ actionId, params }: AppletActionMessageOptions);
93
- }
94
- export declare class AppletInitMessage extends AppletMessage {
95
- constructor();
96
- }
97
- export type AppletMessageType = 'action' | 'actions' | 'data' | 'init' | 'ready' | 'style' | 'resolve' | 'resize';
98
- export type AppletMessageCallback = (message: AppletMessage) => Promise<void> | void;
99
- export declare class AppletDataEvent extends Event {
100
- data: any;
101
- constructor({ data }: {
102
- data: any;
103
- });
104
- }
105
- export declare class AppletReadyEvent extends Event {
106
- constructor();
107
- }
108
- export declare class AppletLoadEvent extends Event {
109
- constructor();
110
- }
111
- export declare class AppletActionsEvent extends Event {
112
- actions: AppletAction[];
113
- constructor({ actions }: {
114
- actions: AppletAction[];
115
- });
116
- }
117
- export interface AppletResizeEventOpts {
118
- dimensions: AppletResizeMessage['dimensions'];
119
- }
120
- export declare class AppletResizeEvent extends Event {
121
- dimensions: AppletResizeMessage['dimensions'];
122
- constructor({ dimensions }: AppletResizeEventOpts);
123
- }
124
- export {};
@@ -1,177 +0,0 @@
1
- /* Manifest & action definitions */
2
- import { parseUrl } from '../utils';
3
- export async function loadManifest(pageUrl) {
4
- pageUrl = parseUrl(pageUrl);
5
- let manifest;
6
- try {
7
- const pageRequest = await fetch(pageUrl);
8
- const html = await pageRequest.text();
9
- const parser = new DOMParser();
10
- const doc = parser.parseFromString(html, 'text/html');
11
- const linkElem = doc.querySelector('link[rel="manifest"]');
12
- const href = linkElem.getAttribute('href');
13
- const manifestUrl = parseUrl(href, pageUrl);
14
- const manifestRequest = await fetch(manifestUrl);
15
- manifest = await manifestRequest.json();
16
- manifest.icons = manifest.icons.map((icon) => {
17
- icon.src = parseUrl(icon.src, pageUrl);
18
- return icon;
19
- });
20
- }
21
- catch (e) {
22
- return;
23
- }
24
- return manifest;
25
- }
26
- export class AppletMessageRelay {
27
- constructor(target) {
28
- this.target = target;
29
- }
30
- async send(message, options) {
31
- this.target.postMessage(message.toJson(), '*');
32
- if (options && options.resolves === false)
33
- return;
34
- // Wait for a resolve message to be sent back before completing await
35
- return new Promise((resolve) => {
36
- const listener = (messageEvent) => {
37
- const responseMessage = new AppletMessage(messageEvent.data.type, messageEvent.data);
38
- if (responseMessage.type === 'resolve' &&
39
- responseMessage.id === message.id) {
40
- window.removeEventListener('message', listener);
41
- resolve(responseMessage);
42
- }
43
- };
44
- window.addEventListener('message', listener);
45
- });
46
- }
47
- async on(messageType, callback) {
48
- const listener = async (messageEvent) => {
49
- if (messageEvent.source === window.self)
50
- return;
51
- if (messageEvent.data.type !== messageType)
52
- return;
53
- if (messageEvent.source !== this.target)
54
- return;
55
- const message = new AppletMessage(messageEvent.data.type, messageEvent.data);
56
- // Wait for the callback to complete, then send a 'resolve' event
57
- // with the message ID.
58
- await callback(message);
59
- const resolveMessage = new AppletResolveMessage({ id: message.id });
60
- this.send(resolveMessage, { resolves: false });
61
- };
62
- window.addEventListener('message', listener);
63
- // TODO: Return something that I can then call .off or .removeListener, implement the
64
- // rest of that event class
65
- }
66
- }
67
- /* Messages */
68
- export class AppletMessage {
69
- constructor(type, values) {
70
- this.timeStamp = Date.now();
71
- this.type = type;
72
- this.id = crypto.randomUUID();
73
- if (values)
74
- Object.assign(this, values);
75
- }
76
- toJson() {
77
- return Object.fromEntries(Object.entries(this).filter(([_, value]) => {
78
- try {
79
- JSON.stringify(value);
80
- return true;
81
- }
82
- catch {
83
- return false;
84
- }
85
- }));
86
- }
87
- }
88
- export class AppletResolveMessage extends AppletMessage {
89
- constructor({ id }) {
90
- super('resolve');
91
- this.id = id;
92
- }
93
- }
94
- export class AppletActionsMessage extends AppletMessage {
95
- constructor({ actions }) {
96
- super('actions');
97
- this.actions = actions;
98
- }
99
- }
100
- export class AppletDataMessage extends AppletMessage {
101
- constructor({ data }) {
102
- super('data');
103
- this.data = data;
104
- }
105
- }
106
- export class AppletReadyMessage extends AppletMessage {
107
- constructor() {
108
- super('ready');
109
- }
110
- }
111
- export class AppletResizeMessage extends AppletMessage {
112
- constructor({ dimensions, }) {
113
- super('resize');
114
- this.dimensions = dimensions;
115
- }
116
- }
117
- export class AppletActionMessage extends AppletMessage {
118
- constructor({ actionId, params }) {
119
- super('action');
120
- this.actionId = actionId;
121
- this.params = params;
122
- }
123
- }
124
- export class AppletInitMessage extends AppletMessage {
125
- constructor() {
126
- super('init');
127
- }
128
- }
129
- /* Events */
130
- export class AppletDataEvent extends Event {
131
- constructor({ data }) {
132
- super('data', {
133
- bubbles: false,
134
- cancelable: false,
135
- composed: false,
136
- });
137
- this.data = data;
138
- }
139
- }
140
- export class AppletReadyEvent extends Event {
141
- constructor() {
142
- super('ready', {
143
- bubbles: false,
144
- cancelable: false,
145
- composed: false,
146
- });
147
- }
148
- }
149
- export class AppletLoadEvent extends Event {
150
- constructor() {
151
- super('load', {
152
- bubbles: false,
153
- cancelable: false,
154
- composed: false,
155
- });
156
- }
157
- }
158
- export class AppletActionsEvent extends Event {
159
- constructor({ actions }) {
160
- super('actions', {
161
- bubbles: false,
162
- cancelable: false,
163
- composed: false,
164
- });
165
- this.actions = actions;
166
- }
167
- }
168
- export class AppletResizeEvent extends Event {
169
- constructor({ dimensions }) {
170
- super('resize', {
171
- bubbles: false,
172
- cancelable: false,
173
- composed: false,
174
- });
175
- this.dimensions = dimensions;
176
- }
177
- }
package/dist/types.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export interface JSONSchema {
2
- type: 'object' | 'string' | 'number' | 'integer' | 'array' | 'boolean' | 'null';
3
- description?: string;
4
- properties?: {
5
- [key: string]: JSONSchema;
6
- };
7
- required?: string[];
8
- additionalProperties?: boolean;
9
- }
File without changes