@omujs/omu 0.9.32 → 0.9.40

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.
Files changed (58) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/dts/api/asset/extension.d.ts +3 -3
  3. package/dist/dts/api/asset/index.d.ts +1 -1
  4. package/dist/dts/api/dashboard/extension.d.ts +13 -3
  5. package/dist/dts/api/dashboard/handler.d.ts +2 -1
  6. package/dist/dts/api/dashboard/index.d.ts +1 -1
  7. package/dist/dts/api/http/extension.d.ts +2 -135
  8. package/dist/dts/api/http/http.d.ts +36 -0
  9. package/dist/dts/api/http/websocket.d.ts +123 -0
  10. package/dist/dts/api/permission/extension.d.ts +1 -0
  11. package/dist/dts/index.d.ts +1 -3
  12. package/dist/dts/version.d.ts +2 -1
  13. package/dist/esm/api/asset/extension.js +43 -18
  14. package/dist/esm/api/asset/index.js +42 -17
  15. package/dist/esm/api/dashboard/extension.js +17 -13
  16. package/dist/esm/api/dashboard/index.js +17 -13
  17. package/dist/esm/api/endpoint/extension.js +3 -3
  18. package/dist/esm/api/extension.js +3 -3
  19. package/dist/esm/api/http/extension.js +262 -277
  20. package/dist/esm/api/http/http.js +442 -0
  21. package/dist/esm/api/http/index.js +262 -165
  22. package/dist/esm/api/http/websocket.js +220 -0
  23. package/dist/esm/api/i18n/extension.js +3 -3
  24. package/dist/esm/api/i18n/index.js +3 -3
  25. package/dist/esm/api/index.js +3 -3
  26. package/dist/esm/api/logger/extension.js +3 -3
  27. package/dist/esm/api/logger/index.js +3 -3
  28. package/dist/esm/api/permission/extension.js +6 -3
  29. package/dist/esm/api/plugin/extension.js +3 -3
  30. package/dist/esm/api/plugin/index.js +3 -3
  31. package/dist/esm/api/registry/extension.js +3 -3
  32. package/dist/esm/api/registry/index.js +3 -3
  33. package/dist/esm/api/server/extension.js +3 -3
  34. package/dist/esm/api/server/index.js +3 -3
  35. package/dist/esm/api/session/extension.js +3 -3
  36. package/dist/esm/api/session/index.js +3 -3
  37. package/dist/esm/api/signal/extension.js +3 -3
  38. package/dist/esm/api/table/extension.js +3 -3
  39. package/dist/esm/api/table/index.js +3 -3
  40. package/dist/esm/index.js +319 -189
  41. package/dist/esm/network/index.js +3 -3
  42. package/dist/esm/network/network.js +3 -3
  43. package/dist/esm/omu.js +318 -186
  44. package/dist/esm/version.js +5 -3
  45. package/package.json +1 -1
  46. package/src/api/asset/extension.ts +46 -12
  47. package/src/api/asset/index.ts +1 -2
  48. package/src/api/dashboard/extension.ts +29 -13
  49. package/src/api/dashboard/handler.ts +2 -1
  50. package/src/api/dashboard/index.ts +2 -0
  51. package/src/api/extension.ts +1 -1
  52. package/src/api/http/extension.ts +13 -364
  53. package/src/api/http/http.ts +79 -0
  54. package/src/api/http/websocket.ts +283 -0
  55. package/src/api/permission/extension.ts +4 -0
  56. package/src/index.ts +3 -5
  57. package/src/version.ts +2 -1
  58. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,283 @@
1
+ import { textDecoder } from '../../const';
2
+ import { DataChunk, RequestHandle } from './http';
3
+
4
+ export type WSData = string | ArrayBufferLike | Blob | ArrayBufferView;
5
+
6
+ export const WSMsgType = {
7
+ CONTINUATION: 0x0,
8
+ TEXT: 0x1,
9
+ BINARY: 0x2,
10
+ PING: 0x9,
11
+ PONG: 0xA,
12
+ CLOSE: 0x8,
13
+ } as const;
14
+
15
+ export const WSCloseCode = {
16
+ OK: 1000,
17
+ GOING_AWAY: 1001,
18
+ PROTOCOL_ERROR: 1002,
19
+ UNSUPPORTED_DATA: 1003,
20
+ ABNORMAL_CLOSURE: 1006,
21
+ INVALID_TEXT: 1007,
22
+ POLICY_VIOLATION: 1008,
23
+ MESSAGE_TOO_BIG: 1009,
24
+ MANDATORY_EXTENSION: 1010,
25
+ INTERNAL_ERROR: 1011,
26
+ SERVICE_RESTART: 1012,
27
+ TRY_AGAIN_LATER: 1013,
28
+ BAD_GATEWAY: 1014,
29
+ } as const;
30
+
31
+ export type WebSocketOpen = RequestHandle & {
32
+ url: string;
33
+ protocol?: string | null;
34
+ };
35
+ export type WebSocketClose = RequestHandle & {
36
+ code?: number;
37
+ reason?: string | null;
38
+ };
39
+ export type WebSocketError = RequestHandle & {
40
+ type: 'ConnectionRefused';
41
+ reason?: string | null;
42
+ };
43
+
44
+ export type EventListenerMap<T> = {
45
+ [K in keyof T]: ((event: T[K]) => unknown)[]
46
+ };
47
+
48
+ export type WSMsg = {
49
+ type: 'open';
50
+ data: WebSocketOpen;
51
+ } | {
52
+ type: 'error';
53
+ data: WebSocketError;
54
+ } | {
55
+ type: 'text';
56
+ data: string;
57
+ } | {
58
+ type: 'binary';
59
+ data: Uint8Array;
60
+ } | {
61
+ type: 'close';
62
+ data: WebSocketClose;
63
+ };
64
+
65
+ export type WebSocketHandle = {
66
+ ws: OmuWS;
67
+ open: (response: WebSocketOpen) => void;
68
+ dispatch: (data: DataChunk<WSDataMeta>) => void;
69
+ close: (response: WebSocketClose) => void;
70
+ error: (response: WebSocketError) => void;
71
+ };
72
+
73
+ export type WSDataMeta = {
74
+ id: string;
75
+ type:
76
+ | typeof WSMsgType.TEXT
77
+ | typeof WSMsgType.BINARY
78
+ | typeof WSMsgType.PING
79
+ | typeof WSMsgType.PONG;
80
+ };
81
+
82
+ export type WSHandleState = {
83
+ type: 'created' | 'receiving';
84
+ handle: WebSocketHandle;
85
+ };
86
+
87
+ type WSOptions = {
88
+ addQueue: (data: WSData) => void;
89
+ dispose(options: {
90
+ code?: number;
91
+ reason?: string;
92
+ }): void;
93
+ };
94
+
95
+ export class OmuWS {
96
+ constructor(
97
+ protected readonly addQueue: (data: WSData) => void,
98
+ protected readonly dispose: (options: { code?: number; reason?: string }) => void,
99
+ protected readonly receiveQueue: WSMsg[] = [],
100
+ private receiveResolve: (() => void) | undefined = undefined,
101
+ private status: 'connecting' | 'open' | 'closed' = 'connecting',
102
+ ) { }
103
+
104
+ public toWebSocket(): OmuWebSocket {
105
+ return new OmuWebSocket(this);
106
+ }
107
+
108
+ public static create(options: WSOptions): WebSocketHandle {
109
+ const ws = new OmuWS(options.addQueue, options.dispose);
110
+ return {
111
+ ws,
112
+ open: (response) => {
113
+ ws.receiveQueue.push({
114
+ type: 'open',
115
+ data: response,
116
+ });
117
+ ws.receiveResolve?.();
118
+ },
119
+ dispatch: (data: DataChunk<WSDataMeta>): void => {
120
+ if (data.meta.type === WSMsgType.BINARY) {
121
+ ws.receiveQueue.push({
122
+ type: 'binary',
123
+ data: data.body,
124
+ });
125
+ } else {
126
+ ws.receiveQueue.push({
127
+ type: 'text',
128
+ data: textDecoder.decode(data.body),
129
+ });
130
+ }
131
+ ws.receiveResolve?.();
132
+ },
133
+ close: (response) => {
134
+ ws.receiveQueue.push({
135
+ type: 'close',
136
+ data: response,
137
+ });
138
+ ws.receiveResolve?.();
139
+ },
140
+ error: (response) => {
141
+ ws.receiveQueue.push({
142
+ type: 'error',
143
+ data: response,
144
+ });
145
+ ws.receiveResolve?.();
146
+ },
147
+ };
148
+ }
149
+
150
+ public send(data: WSData): void {
151
+ this.addQueue(data);
152
+ }
153
+
154
+ public close(code?: number, reason?: string): void {
155
+ this.dispose({ code, reason });
156
+ }
157
+
158
+ public async receive(): Promise<WSMsg> {
159
+ if (this.receiveResolve) {
160
+ throw new Error('Already receiving from another async call');
161
+ }
162
+ while (this.status !== 'closed') {
163
+ const data = this.receiveQueue.shift();
164
+ if (!data) {
165
+ await new Promise<void>((resolve) => this.receiveResolve = resolve);
166
+ continue;
167
+ }
168
+ if (data.type === 'close') {
169
+ this.status = 'closed';
170
+ }
171
+ if (data.type === 'open') {
172
+ this.status = 'open';
173
+ }
174
+ this.receiveResolve = undefined;
175
+ return data;
176
+ }
177
+ throw new Error('Receiving on already closed socket');
178
+ }
179
+
180
+ protocol: string = '';
181
+ url: string = '';
182
+ }
183
+
184
+ export class OmuWebSocket implements WebSocket {
185
+ public CONNECTING = 0 as const;
186
+ public OPEN = 1 as const;
187
+ public CLOSING = 2 as const;
188
+ public CLOSED = 3 as const;
189
+
190
+ binaryType: BinaryType = 'blob';
191
+ bufferedAmount: number = 0;
192
+ extensions: string = '';
193
+ onclose: ((this: WebSocket, ev: CloseEvent) => unknown) | null = null;
194
+ onerror: ((this: WebSocket, ev: Event) => unknown) | null = null;
195
+ onmessage: ((this: WebSocket, ev: MessageEvent) => unknown) | null = null;
196
+ onopen: ((this: WebSocket, ev: Event) => unknown) | null = null;
197
+ protocol: string = '';
198
+ readyState: 0 | 2 | 1 | 3 = 0;
199
+ url: string = '';
200
+
201
+ constructor(
202
+ protected readonly ws: OmuWS,
203
+ private readonly eventListeners: EventListenerMap<WebSocketEventMap> = {
204
+ close: [],
205
+ error: [],
206
+ message: [],
207
+ open: [],
208
+ },
209
+ ) {
210
+ this.receiveLoop();
211
+ }
212
+
213
+ private async receiveLoop() {
214
+ while (this.readyState === WebSocket.CLOSED) {
215
+ const { data, type } = await this.ws.receive();
216
+ switch (type) {
217
+ case 'close':
218
+ this.dispatchEvent(new CloseEvent('close', {
219
+ code: data.code,
220
+ reason: data.reason ?? undefined,
221
+ }));
222
+ break;
223
+ case 'open':
224
+ this.url = data.url;
225
+ this.protocol = data.protocol ?? '';
226
+ this.dispatchEvent(new Event('open', {}));
227
+ break;
228
+ case 'error':
229
+ this.dispatchEvent(new ErrorEvent('error', {
230
+ error: data.type,
231
+ message: data.reason ?? undefined,
232
+ }));
233
+ break;
234
+ case 'text':
235
+ case 'binary':
236
+ this.dispatchEvent(new MessageEvent('message', {
237
+ data,
238
+ }));
239
+ break;
240
+ }
241
+ }
242
+ }
243
+
244
+ dispatchEvent(event: Event): boolean {
245
+ const listeners = this.eventListeners[event.type];
246
+ for (const listener of listeners) {
247
+ listener(event);
248
+ }
249
+ if (event.type === 'open') {
250
+ this.onopen?.(event as MessageEvent);
251
+ }
252
+ if (event.type === 'error') {
253
+ this.onerror?.(event);
254
+ }
255
+ if (event.type === 'message') {
256
+ this.onmessage?.(event as MessageEvent);
257
+ }
258
+ if (event.type === 'close') {
259
+ this.onclose?.(event as CloseEvent);
260
+ }
261
+ return true;
262
+ }
263
+
264
+ send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {
265
+ this.ws.send(data);
266
+ }
267
+
268
+ close(code?: number, reason?: string): void {
269
+ this.ws.close(code, reason);
270
+ }
271
+
272
+ addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => unknown): void {
273
+ this.eventListeners[type].push(listener);
274
+ }
275
+
276
+ removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => unknown): void {
277
+ const listeners = this.eventListeners[type];
278
+ const index = listeners.indexOf(listener);
279
+ if (index !== -1) {
280
+ listeners.splice(index, 1);
281
+ }
282
+ }
283
+ }
@@ -100,4 +100,8 @@ export class PermissionExtension {
100
100
  public has(permissionIdentifier: Identifier): boolean {
101
101
  return this.permissions.has(permissionIdentifier);
102
102
  }
103
+
104
+ public required(permissionIdentifier: Identifier): boolean {
105
+ return this.requiredPermissions.has(permissionIdentifier);
106
+ }
103
107
  }
package/src/index.ts CHANGED
@@ -6,7 +6,7 @@ export { Omu } from './omu.js';
6
6
  export { Serializer } from './serialize';
7
7
  export type { Serializable } from './serialize';
8
8
  export { BrowserTokenProvider, type SessionParam, type TokenProvider } from './token';
9
- import { ASSET_DELETE_PERMISSION_ID, ASSET_DOWNLOAD_PERMISSION_ID, ASSET_UPLOAD_PERMISSION_ID } from './api/asset';
9
+ import { ASSET_PERMISSION_ID } from './api/asset';
10
10
  import {
11
11
  DASHBOARD_APP_INSTALL_PERMISSION_ID,
12
12
  DAShBOARD_DRAG_DROP_PERMISSION_ID,
@@ -29,7 +29,7 @@ import { Identifier } from './identifier';
29
29
 
30
30
  export const OmuPermissions: {
31
31
  // Asset API
32
- readonly ASSET_DELETE_PERMISSION_ID: Identifier; readonly ASSET_DOWNLOAD_PERMISSION_ID: Identifier; readonly ASSET_UPLOAD_PERMISSION_ID: Identifier;
32
+ readonly ASSET_PERMISSION_ID: Identifier;
33
33
  // Dashboard API
34
34
  readonly DASHBOARD_APP_INSTALL_PERMISSION_ID: Identifier; readonly DAShBOARD_DRAG_DROP_PERMISSION_ID: Identifier; readonly DASHBOARD_OPEN_APP_PERMISSION_ID: Identifier; readonly DASHBOARD_SET_PERMISSION_ID: Identifier; readonly DASHBOARD_SPEECH_RECOGNITION_PERMISSION_ID: Identifier; readonly DASHBOARD_WEBVIEW_PERMISSION_ID: Identifier; readonly DASHOBARD_APP_EDIT_PERMISSION_ID: Identifier; readonly DASHOBARD_APP_READ_PERMISSION_ID: Identifier;
35
35
  // HTTP API
@@ -50,9 +50,7 @@ export const OmuPermissions: {
50
50
  readonly TABLE_PERMISSION_ID: Identifier;
51
51
  } = {
52
52
  // Asset API
53
- ASSET_DELETE_PERMISSION_ID,
54
- ASSET_DOWNLOAD_PERMISSION_ID,
55
- ASSET_UPLOAD_PERMISSION_ID,
53
+ ASSET_PERMISSION_ID: ASSET_PERMISSION_ID,
56
54
  // Dashboard API
57
55
  DASHBOARD_APP_INSTALL_PERMISSION_ID,
58
56
  DAShBOARD_DRAG_DROP_PERMISSION_ID,
package/src/version.ts CHANGED
@@ -1 +1,2 @@
1
- export const VERSION = '0.9.31';
1
+ export const VERSION = '0.9.40';
2
+ export const VERSION_MINOR = '0.9.0';