@kemu-io/hs 0.6.7 → 0.8.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.
package/cjs/service.d.ts CHANGED
@@ -182,16 +182,44 @@ export type TargetOutput = {
182
182
  /** id of the variant that defined the output */
183
183
  variantId?: string;
184
184
  };
185
- export type ValidEventContextValue = string | number | boolean | null | ValidEventContextValue[] | {
186
- [key: string]: ValidEventContextValue;
185
+ /**
186
+ * Information about a recipe.
187
+ */
188
+ export type RecipeContextInfo = {
189
+ /** a unique identifier set during recipe creation. It is meant to be unique and universal across all recipes */
190
+ uuid: string;
191
+ /** the id of the recipe in the database (if saved to the cloud) */
192
+ dbId?: string;
193
+ /** the id of the recipe in the pool */
194
+ poolId: string;
195
+ /** the name of the recipe */
196
+ name: string;
197
+ /** the type of recipe */
198
+ type: RecipeType;
199
+ /** the current version number of the recipe */
200
+ version: number;
201
+ /** the id of the author of the recipe */
202
+ authorId: string;
203
+ };
204
+ export type ValidEventContextValue = {
205
+ [key: string]: ValidEventContextValue | string | number | boolean | null;
187
206
  };
188
207
  export type WidgetType = string;
189
208
  export type SerializableWidgetInfo<T> = {
190
209
  /** the id of the current widget in the recipe */
191
210
  readonly widgetId: string;
192
211
  readonly type: WidgetType;
212
+ /**
213
+ * the id of the recipe in the pool
214
+ * @deprecated use `recipe.poolId` instead
215
+ **/
193
216
  readonly recipeId: string;
217
+ /**
218
+ * the name of the recipe
219
+ * @deprecated use `recipe.name` instead
220
+ */
194
221
  readonly recipeName: string;
222
+ readonly recipe: RecipeContextInfo;
195
223
  readonly variantId?: string;
196
224
  /** the state of the widget at the time the event was produced */
197
225
  readonly currentState: Readonly<T>;
@@ -269,18 +297,59 @@ export type ParentEventHandlerEvent<T extends WidgetState = WidgetState> = {
269
297
  /** information about the target (this) widget */
270
298
  target: PortEventInfo;
271
299
  targetVariantId?: string;
300
+ /**
301
+ * the id of the recipe in the pool
302
+ * @deprecated use `recipe.poolId` instead
303
+ */
272
304
  recipeId: string;
305
+ /**
306
+ * the name of the recipe
307
+ * @deprecated use `recipe.name` instead
308
+ */
273
309
  recipeName: string;
310
+ recipe: {
311
+ /**
312
+ * a unique identifier set during recipe creation. It is meant to be unique and universal across all recipes
313
+ */
314
+ uuid: string;
315
+ /**
316
+ * the id of the recipe in the database (if saved to the cloud)
317
+ */
318
+ dbId?: string;
319
+ /**
320
+ * the id of the recipe in the pool
321
+ */
322
+ poolId: string;
323
+ /**
324
+ * the name of the recipe
325
+ */
326
+ name: string;
327
+ /**
328
+ * the type of recipe
329
+ */
330
+ type: RecipeType;
331
+ /**
332
+ * the current version number of the recipe
333
+ */
334
+ version: number;
335
+ /**
336
+ * the id of the author of the recipe
337
+ */
338
+ authorId: string;
339
+ };
274
340
  /**
275
341
  * A context previously set by a parent widget of the same type.
276
342
  */
277
343
  eventContext?: ValidEventContextValue;
344
+ /** Execution path that led to the current invocation. */
345
+ currentPath: string[];
346
+ eventId: number | null;
278
347
  /** when data.value is binary (ImageData, etc) */
279
348
  /** the current state of the widget at the time of invocation */
280
349
  currentState: T;
281
350
  config?: RIExecuteConfig;
282
351
  };
283
- export type ServiceParentEvent<WS extends WidgetState = WidgetState> = Pick<ParentEventHandlerEvent<WS>, "data" | "source" | "target" | "eventContext">;
352
+ export type ServiceParentEvent<WS extends WidgetState = WidgetState> = Pick<ParentEventHandlerEvent<WS>, "data" | "source" | "target" | "eventContext" | "currentPath" | "eventId">;
284
353
  export type ServiceParentEventHandler<T extends WidgetState = WidgetState> = (event: ServiceParentEvent<T>, context: WidgetContext<T>) => Promise<void>;
285
354
  /**
286
355
  * Handles custom ui events. Any returned value will be passed back to the caller.
@@ -298,8 +367,12 @@ export type EnvironmentInfo<T extends WidgetState = WidgetState> = {
298
367
  widgetId: string;
299
368
  /** the id of the widget variant */
300
369
  variantId?: string;
301
- /** the id of the recipe in the pool. */
370
+ /**
371
+ * the id of the recipe in the pool
372
+ * @deprecated use `recipe.poolId` instead
373
+ */
302
374
  recipeId: string;
375
+ recipe: RecipeContextInfo;
303
376
  /** the current state of the widget */
304
377
  currentState: Readonly<T>;
305
378
  /**
@@ -315,14 +388,19 @@ export type EnvironmentInfo<T extends WidgetState = WidgetState> = {
315
388
  */
316
389
  export type GetDefaultStateHandler<T extends WidgetState = WidgetState> = () => T | Promise<T>;
317
390
  export type TerminateContext<T extends WidgetState = WidgetState> = {
391
+ /** @deprecated use `recipe.poolId` instead */
318
392
  recipeId: string;
393
+ recipe: RecipeContextInfo;
319
394
  widgetId: string;
320
395
  variantId?: string;
321
396
  currentState: Readonly<T>;
322
397
  };
323
398
  export type InitializeContext<T extends WidgetState = WidgetState> = {
399
+ /** @deprecated use `recipe.poolId` instead */
324
400
  recipeId: string;
401
+ /** @deprecated use `recipe.name` instead */
325
402
  recipeName: string;
403
+ recipe: RecipeContextInfo;
326
404
  widgetId: string;
327
405
  variantId?: string;
328
406
  currentState: Readonly<T>;
@@ -333,6 +411,13 @@ export type InitializeContext<T extends WidgetState = WidgetState> = {
333
411
  * This is only populated win web-mode when the service is initialized.
334
412
  */
335
413
  kemuApiKey?: string;
414
+ secrets: {
415
+ /**
416
+ * Tells Kemu-Composer the service needs access to a secret. Calling this method allows the secret to appear in the
417
+ * Secrets Mapping modal.
418
+ **/
419
+ requestAccess: (names: string[]) => void;
420
+ };
336
421
  };
337
422
  export type InitializeServiceHandler<T extends WidgetState = WidgetState> = (context: InitializeContext<T>) => Promise<T | null | void | undefined>;
338
423
  export type TerminateServiceHandler<T extends WidgetState = WidgetState> = (context: TerminateContext<T>) => Promise<void>;
@@ -352,6 +437,8 @@ export type ServiceBroadcastConfig = {
352
437
  * The id of the recipe the event is intended for.
353
438
  * If not provided, the event is broadcast to all recipes.
354
439
  */
440
+ targetRecipePoolId?: string;
441
+ /** @deprecated use `targetRecipePoolId` instead */
355
442
  targetRecipeId?: string;
356
443
  /**
357
444
  * The id of the widget the event is intended for.
@@ -364,6 +451,16 @@ export type ServiceBroadcastConfig = {
364
451
  * if the event data has fundamentally changed.
365
452
  */
366
453
  eventContext?: ValidEventContextValue;
454
+ /**
455
+ * The execution path that led to the current invocation.
456
+ */
457
+ currentPath: string[];
458
+ /**
459
+ * The id of the event to forward if this broadcast is the continuation of a previous invocation.
460
+ * Set it to 'null' to auto-generate an event. Default is 'null'
461
+ * If not provided, the event is broadcast to all recipes.
462
+ */
463
+ eventId?: number;
367
464
  };
368
465
  /**
369
466
  * Instance of a Kemu Widget library. Used by Widget services to integrate with the Kemu Hub.
@@ -385,6 +482,16 @@ export type KemuService<T extends Record<string, any> = Record<string, any>> = {
385
482
  * Use it to clean up resources of an instance before it is terminated.
386
483
  */
387
484
  onTerminate: (cb: TerminateServiceHandler<T>) => void;
485
+ /**
486
+ * Invoked when a Kemu Composer instance is disconnected.
487
+ */
488
+ onKemuComposerDisconnected: (cb: (config: {
489
+ /**
490
+ * Information about the recipe that was running in the Kemu Composer instance when it was disconnected.
491
+ * Use this to clean up resources of the service for this recipe.
492
+ **/
493
+ recipe: RecipeContextInfo;
494
+ }) => void) => void;
388
495
  /**
389
496
  * Invoked when a service instance is added to the workspace (in Kemu Compose)
390
497
  * or a recipe is loaded.
@@ -443,7 +550,13 @@ export type KemuService<T extends Record<string, any> = Record<string, any>> = {
443
550
  *
444
551
  * @param config the configuration of the broadcast event.
445
552
  */
446
- broadcastEvent: (config: ServiceBroadcastConfig) => Promise<void>;
553
+ broadcastEvent: (config: Omit<ServiceBroadcastConfig, "currentPath"> & {
554
+ currentPath?: string[];
555
+ }) => Promise<void>;
556
+ /**
557
+ * Sends data to a target recipe.
558
+ * @param config the configuration of the send to recipe event.
559
+ */
447
560
  /**
448
561
  * Registers the path to a file or folder the recipe depends on. When the recipe is exported,
449
562
  * the dependency will be included in the generated package.
@@ -473,6 +586,20 @@ export type KemuService<T extends Record<string, any> = Record<string, any>> = {
473
586
  * @param depPath the relative path of the dependency in the recipe.
474
587
  */
475
588
  resolveRuntimeDependencyPath: (depPath: string) => string;
589
+ /**
590
+ * Access to the secrets of the service.
591
+ */
592
+ secrets: {
593
+ /**
594
+ * Reads the value of a secret.
595
+ * @param name the name of the secret to read
596
+ * @returns a map of secret names to their values, or null if the secret as not been mapped to the recipe
597
+ **/
598
+ read: (config: {
599
+ names: string[];
600
+ recipeUuid: string;
601
+ }) => Promise<Record<string, string | null>>;
602
+ };
476
603
  };
477
604
  export declare const KemuHubServiceId = 0;
478
605
  /**
package/cjs/service.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("fs/promises"),t=require("minimist"),r=require("path"),n=require("node-ipc"),o=require("debug");function a(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var i,s={},c={},d={};var u,l={};var f,g={};var p,m={};var y,S={};var v,b,h={};function I(){return b||(b=1,e=c,w=c&&c.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),P=c&&c.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||w(t,e,r)},Object.defineProperty(e,"__esModule",{value:!0}),P((i||(i=1,Object.defineProperty(d,"__esModule",{value:!0}),d.DataTypeStr=d.DataType=d.RecipeType=void 0,function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}(t||(d.RecipeType=t={})),function(e){e[e.Number=0]="Number",e[e.String=1]="String",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Array=3]="Array",e[e.Boolean=4]="Boolean",e[e.JsonObj=5]="JsonObj",e[e.Anything=6]="Anything",e[e.ImageData=7]="ImageData",e[e.AudioBuffer=8]="AudioBuffer",e[e.Rect=9]="Rect",e[e.Point=10]="Point",e[e.ImageBitmap=11]="ImageBitmap",e[e.BinaryFile=12]="BinaryFile"}(r||(d.DataType=r={})),function(e){e.Number="Number",e.String="String",e.ArrayBuffer="ArrayBuffer",e.Array="Array",e.Boolean="Boolean",e.JsonObj="JsonObj",e.Anything="Anything",e.ImageData="ImageData",e.AudioBuffer="AudioBuffer",e.Rect="Rect",e.Point="Point",e.ImageBitmap="ImageBitmap",e.BinaryFile="BinaryFile"}(n||(d.DataTypeStr=n={}))),d),e),P((u||(u=1,Object.defineProperty(l,"__esModule",{value:!0})),l),e),P((f||(f=1,Object.defineProperty(g,"__esModule",{value:!0})),g),e),P((p||(p=1,Object.defineProperty(m,"__esModule",{value:!0}),m.ProcessorType=void 0,function(e){e.Javascript="js",e.Python="py",e.Executable="exe"}(o||(m.ProcessorType=o={}))),m),e),P((y||(y=1,Object.defineProperty(S,"__esModule",{value:!0}),S.Transport=S.ServiceToServiceFunctions=S.KemuHubFunctions=S.KemuHubCommand=void 0,function(e){e.IpcAcknowledge="iack:",e.SocketAcknowledge="sack:",e.AcknowledgeResponse="ackr:",e.ServicesListChanged="update-services",e.SendManifest="send-manifest",e.BroadcastStart="broadcast-start",e.BroadcastEnd="broadcast-end",e.AssumeSession="assume:"}(a||(S.KemuHubCommand=a={})),function(e){e.GetServices="getServices",e.SubscribeToService="subscribeToService",e.UnsubscribeFromService="unsubscribeFromService",e.GetServiceContents="getServiceContents",e.SocketAckResponse="socketAckResponse",e.ShowSecretsConfigScreen="showSecretsConfigScreen",e.GetMappedSecrets="getMappedSecrets",e.GetSecretContexts="getSecretContexts",e.OnParentEvent="onParentEvent",e.GetDefaultState="getDefaultState",e.BroadcastEvent="broadcastEvent",e.HubBroadcastEvent="hubBroadcastEvent",e.ServiceManifest="serviceManifest",e.GetState="getState",e.SetState="setState",e.SetOutputs="setOutputs",e.UIEvent="uiEvent",e.GetSystemInfo="getSystemInfo",e.InitializeInstance="initializeInstance",e.TerminateInstance="terminateInstance",e.UninstallService="uninstallService",e.ChooseDirectoryDialog="chooseDirectoryDialog",e.ChooseFileDialog="chooseFileDialog",e.GetUniqueId="getUniqueId",e.RebootToInstallUpdate="rebootToInstallUpdate",e.GetFileContentFromCacheId="getFileContentFromCacheId",e.GetDecryptedEdgeApiKey="getDecryptedEdgeApiKey",e.GetHubConfig="getHubConfig"}(s||(S.KemuHubFunctions=s={})),function(e){e.SetDependencyPath="setDependencyPath",e.GetDependencyPath="getDependencyPath"}(I||(S.ServiceToServiceFunctions=I={})),function(e){e.IPC="ipc",e.WS="ws"}(L||(S.Transport=L={}))),S),e),P((v||(v=1,Object.defineProperty(h,"__esModule",{value:!0})),h),e)),c;var e,t,r,n,o,a,s,I,L,w,P}var L,w={};var P,A={};function H(){if(P)return A;P=1,Object.defineProperty(A,"__esModule",{value:!0}),A.onAssumeSession=A.buildIpcAckResponse=A.isBrowser=A.onSendManifestCommand=A.onEndBroadcastCommand=A.onStartBroadcastCommand=A.onAckResponse=A.onAckRequest=A.buildSocketAckRequest=A.buildIpcAckRequest=A.buildAckResponse=A.safeJsonParse=void 0;const e=I();A.safeJsonParse=e=>{try{return JSON.parse(e)}catch(e){return null}};A.buildAckResponse=t=>`${e.KemuHubCommand.AcknowledgeResponse}${t}`;A.buildIpcAckResponse=(t,r)=>`${e.KemuHubCommand.AcknowledgeResponse}${t}:${r||""}`;A.buildIpcAckRequest=()=>`${e.KemuHubCommand.IpcAcknowledge}`;A.buildSocketAckRequest=t=>`${e.KemuHubCommand.SocketAcknowledge}${t}`;A.onAssumeSession=(t,r)=>{if(t.startsWith(e.KemuHubCommand.AssumeSession)){const n=t.split(e.KemuHubCommand.AssumeSession);return r(parseInt(n[1])),!0}return!1};A.onAckResponse=(t,r)=>{if(t.startsWith(e.KemuHubCommand.AcknowledgeResponse)){const n=t.split(e.KemuHubCommand.AcknowledgeResponse),o=parseInt(n[1]);return r&&r(o),o}return null};A.onAckRequest=(t,r)=>{const n=e.KemuHubCommand.SocketAcknowledge,o=e.KemuHubCommand.IpcAcknowledge,a=t.startsWith(n),i=t.startsWith(o);if(a||i){const e=t.split(a?n:o),i=parseInt(e[1]);return r&&r(i),i}return null};A.onStartBroadcastCommand=(t,r)=>t===e.KemuHubCommand.BroadcastStart&&(r(),!0);A.onEndBroadcastCommand=(t,r)=>t===e.KemuHubCommand.BroadcastEnd&&(r(),!0);A.onSendManifestCommand=(t,r)=>t===e.KemuHubCommand.SendManifest&&(r(),!0);const t="undefined"!=typeof window;return A.isBrowser=t,A}var K,C={};var B,E={},j={};var _,k={},z={},D={};function U(){return _||(_=1,e=D,Object.defineProperty(e,"__esModule",{value:!0}),e.KLCmdHeaderSize=e.KLHeaderSize=e.KLCmdProtocolHeaderSize=e.KLProtocolHeadersSize=void 0,e.KLProtocolHeadersSize={protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8},e.KLCmdProtocolHeaderSize={protocolPrefix:4,txtLength:4},e.KLHeaderSize=Object.values(e.KLProtocolHeadersSize).reduce(((e,t)=>e+t),0),e.KLCmdHeaderSize=Object.values(e.KLCmdProtocolHeaderSize).reduce(((e,t)=>e+t),0)),D;var e}var M,O={};function R(){if(M)return O;M=1,Object.defineProperty(O,"__esModule",{value:!0}),O.setNestedProperty=O.decodeMap=O.isSupportedBinaryType=O.getEncodedMap=void 0;const e=["width","height","colorSpace"],t=e=>{const t="undefined"!=typeof Buffer&&e instanceof Buffer,r=e instanceof ArrayBuffer,n=e instanceof Uint8ClampedArray,o=e instanceof Uint8Array,a=e instanceof Int8Array;return t?"Buffer":r?"ArrayBuffer":n?"Uint8ClampedArray":o?"Uint8Array":a?"Int8Array":null};O.isSupportedBinaryType=t;O.getEncodedMap=(r,n)=>{const o={},a=[];let i=0,s=Array.isArray(r)?[]:{};const c=(r,s)=>{const d=t(r);if(!d){if(Array.isArray(r)){const e=[];for(let t=0;t<r.length;t++)e[t]=c(r[t],`${s}[${t}]`);return e}if("object"==typeof r){const t={},n=(e=>{const t=e instanceof Int16Array,r=e instanceof Uint16Array,n=e instanceof Int32Array,o=e instanceof Uint32Array,a=e instanceof Float32Array,i=e instanceof Float64Array,s=e instanceof BigInt64Array,c=e instanceof BigUint64Array;return t?"Int16Array":r?"Uint16Array":n?"Int32Array":o?"Uint32Array":a?"Float32Array":i?"Float64Array":s?"BigInt64Array":c?"BigUint64Array":null})(r);if(n)throw new Error(`Unsupported binary type [${n}] at path "${s}"`);for(const n in r)Object.hasOwn(r,n)||e.includes(n)||console.warn(`Allowing inherited property: ${n} from path: ${s}`),t[n]=c(r[n],`${s.length?`${s}.`:""}${n}`);return t}return r}o[s]={index:i,length:r.byteLength,binaryType:d},"Buffer"===n?a.push(Buffer.from(r)):"ArrayBuffer"===d?a.push(r):a.push(r.buffer),i+=r.byteLength};s=c(r,"");let d=null;if(a.length>1)if("ArrayBuffer"===n){const e=a.reduce(((e,t)=>e+t.byteLength),0),t=new Uint8Array(e);let r=0;for(let e=0;e<a.length;e++)t.set(new Uint8Array(a[e]),r),r+=a[e].byteLength;d=t.buffer}else{d=Buffer.concat(a)}else 1===a.length&&(d=a[0]);return d?{map:o,combinedData:d,sourceCopy:s}:null};const r=(e,t,r,n)=>{const o=t.match(/(\[\d+\])|([^[\].]+)/g)||[];let a=e;for(let e=0;e<o.length;e++){let t=o[e];const i=t.startsWith("[")&&t.endsWith("]"),s=e===o.length-1;if(i){t=t.slice(1,-1);const i=parseInt(t,10);if(!Array.isArray(a))throw new Error(`Expected an array at key "${o.slice(0,e).join(".")}" but found an object.`);s?n?a.splice(i,1):a[i]=r:(a[i]||(a[i]=o[e+1].startsWith("[")?[]:{}),a=a[i])}else s?n?delete a[t]:a[t]=r:(a[t]||(a[t]=o[e+1].startsWith("[")?[]:{}),a=a[t])}return e};O.setNestedProperty=r;return O.decodeMap=(e,t,n)=>{const o="undefined"!=typeof Buffer,a=t instanceof Uint8Array;for(const i in n)if(Object.hasOwn(n,i)){const{index:s,length:c,binaryType:d}=n[i];let u=null;if(o&&t instanceof Buffer)switch(d){case"Buffer":u=t.subarray(s,s+c);break;case"ArrayBuffer":u=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(s,s+c);break;case"Uint8Array":u=new Uint8Array(t.subarray(s,s+c));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.subarray(s,s+c));break;case"Int8Array":u=new Int8Array(t.subarray(s,s+c))}else if(t instanceof ArrayBuffer||t instanceof Uint8Array)switch(d){case"Buffer":if(o){u=Buffer.from(t.slice(s,s+c));break}case"ArrayBuffer":u=a?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(s,s+c):t.slice(s,s+c);break;case"Uint8Array":u=a?t.slice(s,s+c):new Uint8Array(t.slice(s,s+c));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.slice(s,s+c));break;case"Int8Array":u=new Int8Array(t.slice(s,s+c))}u&&r(e,i,u)}return e},O}var x,T,$={};function F(){if(x)return $;x=1;var e=$&&$.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty($,"__esModule",{value:!0}),$.createLogger=void 0;const t=e(o);return $.createLogger=e=>(0,t.default)(e),$}function N(){if(T)return z;T=1,Object.defineProperty(z,"__esModule",{value:!0});const e=H(),t=U(),r=R(),n=F(),o="KMSG",a="KCMD",i=(0,n.createLogger)("klProtocol");return z.default={encode:(e,n,a)=>{const i={json:e.json},s=(0,r.getEncodedMap)(i.json,"Buffer"),c=s?.combinedData;s&&(i.jsonBinaryMap=s.map,i.json=s.sourceCopy);const d=c?c.byteLength:0,u=JSON.stringify(i),l=Buffer.from(u),f=l.byteLength,g=t.KLProtocolHeadersSize.protocolPrefix+t.KLProtocolHeadersSize.protocolVersion+t.KLProtocolHeadersSize.jsonLength+t.KLProtocolHeadersSize.binaryLength+t.KLProtocolHeadersSize.fromServiceId+t.KLProtocolHeadersSize.toServiceId+t.KLProtocolHeadersSize.sentAt+f+d,p=Buffer.alloc(g),m=Date.now();let y=0;return p.write(o,y),y+=t.KLProtocolHeadersSize.protocolPrefix,p.writeUInt8(1,y),y+=t.KLProtocolHeadersSize.protocolVersion,p.writeUInt32LE(f,y),y+=t.KLProtocolHeadersSize.jsonLength,p.writeUInt32LE(d,y),y+=t.KLProtocolHeadersSize.binaryLength,p.writeUInt32LE(n,y),y+=t.KLProtocolHeadersSize.fromServiceId,p.writeUInt32LE(a,y),y+=t.KLProtocolHeadersSize.toServiceId,p.writeBigInt64LE(BigInt(m),y),y+=t.KLProtocolHeadersSize.sentAt,l.copy(p,y),y+=f,c&&d&&c.copy(p,y),p},decodeHeader:e=>{let r=0;const n=e.toString("utf-8",r,t.KLProtocolHeadersSize.protocolPrefix);if(r+=t.KLProtocolHeadersSize.protocolPrefix,n!==o)return null;if(e.byteLength<t.KLHeaderSize)return i(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const a=e.readUInt8(r);r+=t.KLProtocolHeadersSize.protocolVersion;const s=e.readUInt32LE(r);r+=t.KLProtocolHeadersSize.jsonLength;const c=e.readUInt32LE(r);r+=t.KLProtocolHeadersSize.binaryLength;const d=e.readUInt32LE(r);r+=t.KLProtocolHeadersSize.fromServiceId;const u=e.readUInt32LE(r);r+=t.KLProtocolHeadersSize.toServiceId;const l=e.readBigInt64LE(r);r+=t.KLProtocolHeadersSize.sentAt;const f=s+c,g=e.subarray(r,r+f),p=e.subarray(0,t.KLHeaderSize);let m=null;return e.byteLength-t.KLHeaderSize-s-c>0&&(m=e.subarray(t.KLHeaderSize+s+c)),{header:{protocolVersion:a,jsonLength:s,binaryLength:c,fromServiceId:d,toServiceId:u,sentAt:new Date(Number(l)),packages:[g],headerPackage:p},remaining:m}},decodeFullKlMessage:n=>{const o=Buffer.concat(n.packages),a=o.subarray(0,n.jsonLength).toString(),s=o.subarray(n.jsonLength,n.jsonLength+n.binaryLength),c=(0,e.safeJsonParse)(a);if(!c?.json)return i("Invalid JSON in KL message"),null;c.jsonBinaryMap&&s.byteLength&&(0,r.decodeMap)(c.json,s,c.jsonBinaryMap);const d=Buffer.concat([n.headerPackage,o]);let u=d,l=null;const f=t.KLHeaderSize+n.jsonLength+n.binaryLength;return d.byteLength>f&&(l=d.subarray(f),u=d.subarray(0,f)),{message:{json:c.json,rawMessage:u},remaining:l}},patchEncodedHeader:(e,r)=>{if(null==r.fromServiceId&&void 0===r.toServiceId)return e;if(e.byteLength<t.KLHeaderSize)return i("Invalid Header Size"),e;let n=0;return n+=t.KLProtocolHeadersSize.protocolPrefix,n+=t.KLProtocolHeadersSize.protocolVersion,n+=t.KLProtocolHeadersSize.jsonLength,n+=t.KLProtocolHeadersSize.binaryLength,void 0!==r.fromServiceId&&e.writeUInt32LE(r.fromServiceId,n),n+=t.KLProtocolHeadersSize.fromServiceId,void 0!==r.toServiceId&&e.writeUInt32LE(r.toServiceId,n),e},encodeCommand:e=>{let r=0;const n=Buffer.from(e),o=n.byteLength,i=t.KLCmdHeaderSize+o,s=Buffer.alloc(i);return s.write(a,r),r+=t.KLCmdProtocolHeaderSize.protocolPrefix,s.writeUint32LE(o,r),r+=t.KLCmdProtocolHeaderSize.txtLength,n.copy(s,r),s},decodeCommand:e=>{let r=0;if(e.byteLength<t.KLCmdHeaderSize)return{command:null};const n=e.toString("utf-8",r,t.KLCmdProtocolHeaderSize.protocolPrefix);if(r+=t.KLCmdProtocolHeaderSize.protocolPrefix,n!==a)return{command:null};const o=e.readUInt32LE(r);r+=t.KLCmdProtocolHeaderSize.txtLength;const i=e.toString("utf-8",r,r+o),s=e.byteLength-t.KLCmdHeaderSize-o;let c=null;s>0&&(c=e.subarray(t.KLCmdHeaderSize+o));let d=0;return s<0&&(d=Math.abs(s)),{command:i,remainingData:c,missing:d}}},z}var G,W,V={};function q(){if(G)return V;G=1,Object.defineProperty(V,"__esModule",{value:!0});const e=U(),t=F(),r=R(),n=H(),o="KMSG",a="KCMD",i=(0,t.createLogger)("klProtocol"),s=new TextEncoder;return V.default={encode:(t,n,a)=>{const i={json:t.json},c=(0,r.getEncodedMap)(t.json,"ArrayBuffer"),d=c?.combinedData;c&&(i.jsonBinaryMap=c.map,i.json=c.sourceCopy);const u=d?d.byteLength:0,l=JSON.stringify(i),f=s.encode(l),g=f.byteLength,p=e.KLProtocolHeadersSize.protocolPrefix+e.KLProtocolHeadersSize.protocolVersion+e.KLProtocolHeadersSize.jsonLength+e.KLProtocolHeadersSize.binaryLength+e.KLProtocolHeadersSize.fromServiceId+e.KLProtocolHeadersSize.toServiceId+e.KLProtocolHeadersSize.sentAt+g+u,m=new ArrayBuffer(p),y=new DataView(m),S=new Uint8Array(m),v=Date.now();let b=0;for(let e=0;e<4;++e)S[b++]=o.charCodeAt(e);return y.setUint8(b,1),b+=e.KLProtocolHeadersSize.protocolVersion,y.setUint32(b,g,!0),b+=e.KLProtocolHeadersSize.jsonLength,y.setUint32(b,u,!0),b+=e.KLProtocolHeadersSize.binaryLength,y.setUint32(b,n,!0),b+=e.KLProtocolHeadersSize.fromServiceId,y.setUint32(b,a,!0),b+=e.KLProtocolHeadersSize.toServiceId,y.setBigInt64(b,BigInt(v),!0),b+=e.KLProtocolHeadersSize.sentAt,S.set(f,b),b+=g,d&&u&&S.set(new Uint8Array(d),b),m},decodeHeader:t=>{const r=new DataView(t);let n=0,a="";for(let t=0;t<e.KLProtocolHeadersSize.protocolPrefix;++t)a+=String.fromCharCode(r.getUint8(n++));if(a!==o)return null;if(t.byteLength<e.KLHeaderSize)return i.log(`Received a Partial Header with ${t.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const s=r.getUint8(n);n+=e.KLProtocolHeadersSize.protocolVersion;const c=r.getUint32(n,!0);n+=e.KLProtocolHeadersSize.jsonLength;const d=r.getUint32(n,!0);n+=e.KLProtocolHeadersSize.binaryLength;const u=r.getUint32(n,!0);n+=e.KLProtocolHeadersSize.fromServiceId;const l=r.getUint32(n,!0);n+=e.KLProtocolHeadersSize.toServiceId;const f=r.getBigInt64(n,!0);n+=e.KLProtocolHeadersSize.sentAt;const g=c+d,p=t.slice(n,n+g),m=new Uint8Array(t,0,e.KLHeaderSize);let y=null;if(t.byteLength-e.KLHeaderSize-c-d>0){y=new Uint8Array(t,e.KLHeaderSize+c+d).slice().buffer}return{header:{protocolVersion:s,jsonLength:c,binaryLength:d,fromServiceId:u,toServiceId:l,sentAt:new Date(Number(f)),packages:[p],headerPackage:m.slice().buffer},remaining:y}},decodeFullKlMessage:t=>{const o=t.packages.reduce(((e,t)=>e+t.byteLength),0),a=new Uint8Array(o);let s,c=0;for(const e of t.packages)s=new Uint8Array(e),a.set(s,c),c+=s.byteLength;const d=(new TextDecoder).decode(a.subarray(0,t.jsonLength)),u=a.subarray(t.jsonLength,t.jsonLength+t.binaryLength),l=(0,n.safeJsonParse)(d);if(!l?.json)return i.log("Invalid JSON in KL message"),null;l.jsonBinaryMap&&u.byteLength&&(0,r.decodeMap)(l.json,u,l.jsonBinaryMap);const f=new Uint8Array(t.headerPackage.byteLength+a.byteLength);f.set(new Uint8Array(t.headerPackage),0),f.set(a,t.headerPackage.byteLength);let g=f,p=null;const m=e.KLHeaderSize+t.jsonLength+t.binaryLength;return f.byteLength>m&&(p=f.subarray(m),g=f.subarray(0,m)),{message:{json:l.json,...u.length?{binaryData:u.buffer}:{},rawMessage:g.buffer},remaining:p?.buffer??null}},patchEncodedHeader:(t,r)=>{if(null==r.fromServiceId&&void 0===r.toServiceId)return t;if(t.byteLength<e.KLHeaderSize)return i("Invalid Header Size"),t;let n=0;n+=e.KLProtocolHeadersSize.protocolPrefix,n+=e.KLProtocolHeadersSize.protocolVersion,n+=e.KLProtocolHeadersSize.jsonLength,n+=e.KLProtocolHeadersSize.binaryLength;const o=new DataView(t);return void 0!==r.fromServiceId&&o.setUint32(n,r.fromServiceId,!0),n+=e.KLProtocolHeadersSize.fromServiceId,void 0!==r.toServiceId&&o.setUint32(n,r.toServiceId,!0),t},encodeCommand:t=>{let r=0;const n=s.encode(t),o=n.byteLength,i=e.KLCmdHeaderSize+o,c=new ArrayBuffer(i),d=new DataView(c),u=new Uint8Array(c);for(let e=0;e<4;++e)u[r++]=a.charCodeAt(e);return d.setUint32(r,o,!0),r+=e.KLCmdProtocolHeaderSize.txtLength,u.set(n,r),c},decodeCommand:t=>{const r=new DataView(t);let n=0;if(t.byteLength<e.KLCmdHeaderSize)return{command:null};let o="";for(let t=0;t<e.KLCmdProtocolHeaderSize.protocolPrefix;++t)o+=String.fromCharCode(r.getUint8(n++));if(o!==a)return{command:null};const i=r.getUint32(n,!0);n+=e.KLCmdProtocolHeaderSize.txtLength;const s=t.byteLength-e.KLCmdHeaderSize-i,c=new Uint8Array(t,n,Math.min(i,t.byteLength-e.KLCmdHeaderSize)),d=(new TextDecoder).decode(c);let u=null;s>0&&(u=t.slice(e.KLCmdHeaderSize+i));let l=0;return s<0&&(l=Math.abs(s)),{command:d,remainingData:u,missing:l}}},V}function J(){if(W)return k;W=1;var e=k&&k.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(k,"__esModule",{value:!0}),k.createTransmissionManager=void 0;const t=e(N()),r=e(q()),n=(0,F().createLogger)("klTransmissionManager");return k.createTransmissionManager=()=>{const e=(o,a,i,s)=>{let c=a,d=null;const u=o instanceof ArrayBuffer;if(n(`RAW: ${o.toString()}`),!c||c.partialHeaderData){let l;if(u?(l=c?.partialHeaderData?new Uint8Array([...new Uint8Array(c.partialHeaderData),...new Uint8Array(o)]).buffer:o,d=r.default.decodeHeader(l)):(l=c?.partialHeaderData?Buffer.concat([c.partialHeaderData,o]):o,d=t.default.decodeHeader(l)),!d){const{command:o,missing:c,remainingData:d}=u?r.default.decodeCommand(l):t.default.decodeCommand(l);return o?s({command:o,complete:!0,rawMessage:l}):n(c?`ERROR: Missing ${c} bytes to complete the command. This partial command will be aborted.`:`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${l.byteLength} bytes`),d?(n(`${d.byteLength} bytes remain after processing command. Re-analyzing...`),e(d,a,i,s)):void 0}if(d.partialHeader)return c={firstPackageAt:Date.now(),partialHeaderData:l},i(c);if(!d.header)return n(`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${l.byteLength} bytes`);const f=d.header;c={firstPackageAt:Date.now(),header:{...f,totalBytesReceived:f.packages[0].byteLength,totalBytesExpected:f.binaryLength+f.jsonLength,remaining:d.remaining}},i(c)}else c.header&&c.header.totalBytesReceived<c.header.totalBytesExpected&&(c.header.packages.push(o),c.header.totalBytesReceived+=o.byteLength,i(c));if(c.header&&c.header.totalBytesReceived>=c.header.totalBytesExpected){const o=Date.now()-c.header.sentAt.getTime(),a=Date.now()-c.firstPackageAt;n(`Received ${c.header.totalBytesReceived} of ${c.header.totalBytesExpected} expected in ${o} ms, elapsed since first package: ${a}ms`);const d=u?r.default.decodeFullKlMessage(c.header):t.default.decodeFullKlMessage(c.header),l=c.header.totalBytesReceived,f=c.header.remaining;i(null),d&&s({klMessage:d.message,complete:!0,sourceServiceId:c.header.fromServiceId,targetServiceId:c.header.toServiceId,rawMessage:d.message.rawMessage});let g=f;if(d?.remaining&&(g=u?f?((e,t)=>{const r=e.byteLength+t.byteLength,n=new ArrayBuffer(r),o=new Uint8Array(e),a=new Uint8Array(t),i=new Uint8Array(n);return i.set(o),i.set(a,o.length),n})(f,d.remaining):d.remaining:f?Buffer.concat([f,d.remaining]):d.remaining),g)return n(`${g.byteLength} bytes remaining after processing message with ${l} bytes of data. Re-analyzing...`),e(g,null,i,s)}};return e},k}var Q,X,Y={};function Z(){if(Q)return Y;Q=1;var e=Y&&Y.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(Y,"__esModule",{value:!0});const t=e(N()),r=e(q()),n=H();let o=t.default;return n.isBrowser&&(o=r.default),Y.default=o,Y}function ee(){if(X)return E;X=1;var e=E&&E.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(E,"__esModule",{value:!0});const t=e(n),r=e((B||(B=1,Object.defineProperty(j,"__esModule",{value:!0}),j.default={id:"widgets",retry:1500,silent:!0,rawBuffer:!0,appspace:"kemu.",encoding:"hex"}),j)),o=J(),a=F(),i=e(Z());let s,c,d,u,l=null;const f=(0,o.createTransmissionManager)(),g=(0,a.createLogger)("ipcClient"),p=e=>{const n=r.default.id;t.default.of[n].emit(e)};return E.default={connect:e=>{r.default.id=e?.id||r.default.id,r.default.appspace=e?.appSpace||r.default.appspace,t.default.config={...t.default.config,...r.default};const n=r.default.id;t.default.connectTo(n,(()=>{t.default.of[n].on("connect",(()=>{g("Connected to server"),l=null,c&&c()})),t.default.of[n].on("data",(e=>{f(e,l,(e=>l=e),(e=>{if(e.complete)return e.command?(g(`Received command: ${e.command}`),void(s&&s(e.command))):void(e.klMessage&&d&&d({send:p,transmission:{sourceServiceId:e.sourceServiceId??-1,targetServiceId:e.targetServiceId??-1,rawMessage:e.rawMessage},json:e.klMessage.json}))}))})),t.default.of[n].on("disconnect",(()=>{g(`Disconnected from ${n}`),l=null,u&&u()}))}))},sendCommand:e=>{const n=r.default.id,o=i.default.encodeCommand(e);t.default.of[n].emit(o)},sendBuffer:p,onCommand:e=>s=e,onMessageReceived:e=>d=e,onClientConnected:e=>c=e,onClientDisconnected:e=>u=e},E}var te,re,ne,oe={},ae={};function ie(){return re||(re=1,function(e){var t=oe&&oe.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),r=oe&&oe.__exportStar||function(e,r){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(r,n)||t(r,e,n)},n=oe&&oe.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0});const o=n(Z()),a=H();var i;r((te||(te=1,Object.defineProperty(ae,"__esModule",{value:!0}),ae.RemoveInvokeError=void 0,function(e){e.FunctionNotFound="FNC_NOT_FOUND",e.ParentEventCallbackError="PARENT_EVENT_CALLBACK_ERROR"}(i||(ae.RemoveInvokeError=i={}))),ae),e);let s=Math.ceil(Date.now()/1e3);e.default=function(e){const t={};let r=console.log;const n={};let i=e||String(Date.now());const c={},d=e=>!c[e],u=(e,t,r,n,i,s)=>{let c=a.isBrowser?new ArrayBuffer(0):Buffer.alloc(0);const u={json:{functionName:e,args:s.success?s.success:[s],messageId:t,type:s.success?"response":"error"}};return d(n)&&(c=o.default.encode(u,r,n)),i(c,{msg:u,sourceServiceId:r,targetServiceId:n})};return{setLogger:e=>{r=e},processMessage:(e,o,a,i)=>{if(!i)return!1;const s=i;if(t[s.messageId]){const e=t[s.messageId];return e&&(clearTimeout(e.timer),e.fulfilled||(e.fulfilled=!0,"response"===s.type?e.resolve(s.args):"error"===s.type&&e.reject(s.args[0])),delete t[s.messageId]),!0}if("execute"!==s.type&&r&&r(`No pending execution found for message id "${s.messageId}"`),"execute"===s.type){const t=n[s.functionName];if(t){const r=e=>{u(s.functionName,s.messageId,a.targetServiceId,a.sourceServiceId,o,e)};t({transport:e,args:s.args,reply:r,messageId:s.messageId,sourceServiceId:a.sourceServiceId,send:o})}else{const e=`Function "${s.functionName}" not found.`;r&&r(e),u(s.functionName,s.messageId,a.targetServiceId,a.sourceServiceId,o,{error:e,errCode:"FNC_NOT_FOUND"})}return!0}return!1},execute:async(e,n,c,u,l,f)=>{if(!c){const e="No send buffer function provided.";throw r&&r(e),e}s+=1;const g=`${i}-${s}-exec-${e.substring(0,10)}`,p={messageId:g,functionName:e,send:c,sourceServiceId:u,targetServiceId:l,args:n||[],fulfilled:!1,resolve:()=>{},reject:()=>{}};p.promise=new Promise(((e,t)=>{p.resolve=e,p.reject=t}));let m=a.isBrowser?new ArrayBuffer(0):Buffer.alloc(0);const y={json:{functionName:e,args:n,messageId:g,type:"execute"}};d(l)&&(m=o.default.encode(y,u,l)),t[g]=p,r&&r(`Calling remote function "${e}" with message id "${g}"`);const S="true"===process.env.NO_INVOKE_TIMEOUT;return f?.async?(p.fulfilled=!0,p.resolve([void 0]),delete t[g]):0===f?.timeout||S||(p.timer=setTimeout((()=>{r&&r(`Remote function ${g} timed out`);const n=t[g];n&&!n.fulfilled&&(n.fulfilled=!0,p.reject(`Function ${e} Timed out`)),delete t[g]}),f?.timeout||3e4)),c(m,{sourceServiceId:u,targetServiceId:l,msg:y}),p.promise},sendResponse:u,registerFunction:(e,t)=>{n[e]=t},getTransportSendFunction:e=>{const r=t[e];return r?r.send:null},setServiceName:e=>{i=e},getPendingExecutions:()=>t,rejectAllPending:e=>{Object.keys(t).forEach((r=>{const n=t[r];n&&!n.fulfilled&&(clearTimeout(n.timer),n.fulfilled=!0,n.reject(e),delete t[r])}))},broadcast:(e,t,n,c)=>{s+=1;const u=`${i}-${s}-multicast-${e.substring(0,10)}`;let l=a.isBrowser?new ArrayBuffer(0):Buffer.alloc(0);const f={json:{functionName:e,args:t,messageId:u,type:"execute"}};let g=d(n[0].serviceId);g&&(l=o.default.encode(f,c,n[0].serviceId));for(let t=0;t<n.length;t++)try{const a=n[t];r&&r(`Broadcasting function "${e}" with message id "${u}" to client [${a.serviceId}]`),0!==t&&(g=d(a.serviceId),g&&(l=o.default.patchEncodedHeader(l,{toServiceId:a.serviceId}))),a.sendFn(l,{msg:f,sourceServiceId:c,targetServiceId:a.serviceId})}catch(e){r&&r(`Error broadcasting to client at index ${t}`)}},disableServiceEncoding:(e,t)=>{c[e]=t}}}}(oe)),oe}var se=a((ne||(ne=1,function(n){var o=s&&s.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.createImageDataLike=n.KemuHubServiceId=n.DataType=void 0;const a=I();Object.defineProperty(n,"DataType",{enumerable:!0,get:function(){return a.DataType}});const i=e,c=o(t),d=o(r),u=(L||(L=1,Object.defineProperty(w,"__esModule",{value:!0}),w.KemuHubServiceId=void 0,w.KemuHubServiceId=0),w);Object.defineProperty(n,"KemuHubServiceId",{enumerable:!0,get:function(){return u.KemuHubServiceId}});const l=H(),f=function(){if(K)return C;K=1,Object.defineProperty(C,"__esModule",{value:!0}),C.preProcessManifest=C.portStrToWidgetPort=C.createImageDataLike=void 0;const e=I();return C.createImageDataLike=(t,r,n,o="srgb")=>{let a;return a=t instanceof Uint8ClampedArray?t:new Uint8ClampedArray(t),{data:a,width:r,height:n,colorSpace:o,_kemuType:e.DataType.ImageData}},C.portStrToWidgetPort=t=>({...t,type:e.DataType[t.type]}),C.preProcessManifest=(e,t,r)=>({...e,path:t,...e.widgetUI&&r?.widgetUIContents?{widgetUIContents:r.widgetUIContents}:{}}),C}();Object.defineProperty(n,"createImageDataLike",{enumerable:!0,get:function(){return f.createImageDataLike}});const g=o(ee()),p=F(),m=o(ie()),y=(0,p.createLogger)("kemuWidgetService"),S=(0,c.default)(process.argv.slice(2));n.default=function(e){const t={},r=process.env.KEMU_WIDGET_SESSION_ID;let n,o,s,c,p=!1;const v={};let b,h,I,L,w,P,A,H=null;const K=new m.default;K.setLogger(y),t.start=async(t,c)=>{const u=t||d.default.resolve(d.default.dirname(process.argv[1]),"manifest.json");s=d.default.dirname(u);const m=await(0,i.readFile)(u,"utf-8"),v=(0,l.safeJsonParse)(m);if(!v)throw new Error("Error parsing manifest file.");let b;if(v.inputs||(v.inputs=[]),v.outputs||(v.outputs=[]),v.widgetUI)try{b=await(0,i.readFile)(d.default.join(s,"widgetUI.js"))}catch(e){y(`Error loading widgetUI file ${v.name}: ${e}`)}if(v.svgIcon)try{const e=await(0,i.readFile)(d.default.join(s,v.svgIcon),"utf-8");v.svgIcon=e}catch(e){y(`Error loading icon for service ${v.name}: ${e}`)}o=(0,f.preProcessManifest)(v,s,{widgetUIContents:b}),p=o.name.startsWith("test."),o.path=s,o.internal=S.internal||!1,p?y("Starting Kemu Service in Dev mode"):((e=>{const t=e||S.sessionId||r;if(!t)throw new Error("Missing sessionId. Expected service to be launched with a sessionId as first argument, or the KEMU_WIDGET_SESSION_ID environment variable to be set.");n=parseInt(String(t))})(c),y(`Starting Kemu Service with session id: ${n}`)),K.setServiceName(`${o.name}_${o.version}`),g.default.onCommand(C),g.default.onMessageReceived((({json:e,transmission:t})=>K.processMessage(a.Transport.IPC,g.default.sendBuffer,t,e))),K.registerFunction(a.KemuHubFunctions.OnParentEvent,E),K.registerFunction(a.KemuHubFunctions.GetDefaultState,B),K.registerFunction(a.KemuHubFunctions.UIEvent,k),K.registerFunction(a.KemuHubFunctions.InitializeInstance,j),K.registerFunction(a.KemuHubFunctions.TerminateInstance,_),g.default.onClientConnected((()=>{A&&A()})),g.default.onClientDisconnected((()=>{p&&(n=void 0)})),g.default.connect({appSpace:S.ipcSpace||e?.ipc?.appSpace,id:S.ipcId||e?.ipc?.id})};const C=e=>{(0,l.onAckRequest)(e,(e=>{g.default.sendCommand((0,l.buildIpcAckResponse)(e,n||void 0)),!n&&p&&(y("Dev mode detected, assuming service session id from ack request:",e),n=e)})),(0,l.onStartBroadcastCommand)(e,(()=>{I&&I()})),(0,l.onEndBroadcastCommand)(e,(()=>{L&&L()})),(0,l.onSendManifestCommand)(e,(()=>{y("Sending manifest to hub"),n?K.execute(a.KemuHubFunctions.ServiceManifest,[{...o,devMode:p}],g.default.sendBuffer,n,u.KemuHubServiceId,{async:!0}):y("Service session id is not set. Cannot send manifest.")})),(0,l.onAssumeSession)(e,(e=>{n=e,y(`Assumed session id ${e}`)}))},B=async e=>{if(h){const t=await h();return e.reply({success:[t]})}return e.reply({success:[{}]})},E=async e=>{if(!b)return y("No onParentEvent callback defined. Skipping parent event."),e.reply({success:[]});const t=e.args[0],{source:r,target:o,data:i,recipeId:s,recipeName:c,currentState:d,targetVariantId:u,eventContext:l}=t;if(!n)return void y("Service session id is not set. Cannot process parent event.");if(!r||!o||!i)return e.reply({error:"Invalid arguments, expected [source, target, data, context]"});const f=g.default.sendBuffer,p=async t=>K.execute(a.KemuHubFunctions.SetOutputs,[t],f,n,e.sourceServiceId,{timeout:0}),m={currentState:d,type:o.widgetType,widgetId:o.widgetId,variantId:u,recipeId:s,recipeName:c,setState:async t=>{const r={widgetId:o.widgetId,variantId:u,recipeId:s,newState:t};return K.execute(a.KemuHubFunctions.SetState,[r],f,n,e.sourceServiceId)},setOutputs:async(e,t)=>{const r={widgetId:o.widgetId,recipeId:s,outputs:e,finalState:t};await p(r)},setOutputsWithContext:async e=>{const t={...e,widgetId:o.widgetId,recipeId:s};await p(t)}};y(`Invoking user-defined onParentEvent callback for event id "${e.messageId}"`),await b({data:i,source:r,target:o,eventContext:l},m).then((()=>{y(`Replying SUCCESS to event id "${e.messageId}"`),e.reply({success:[]})})).catch((t=>{const r="string"==typeof t?t:t.message||t;y(`Error invoking onParentEvent callback: ${r}`),e.reply({error:r,errCode:"PARENT_EVENT_CALLBACK_ERROR"})}))},j=async e=>{const[{currentState:t,recipeId:r,recipeName:n,widgetId:o,variantId:a,recipeType:i,currentDependencies:s,kemuApiKey:d}]=e.args;if(d&&(c=d),v[o]={currentRecipeId:r,variantId:a,currentSourceServiceId:e.sourceServiceId},w){const c={currentState:t,recipeId:r,recipeName:n,widgetId:o,variantId:a,recipeType:i,currentDependencies:s||{},kemuApiKey:d},u=await w(c);e.reply({success:[u]})}else e.reply({error:"Not implemented",errCode:"FNC_NOT_FOUND"})},_=async e=>{if(P){const[{currentState:t,recipeId:r,widgetId:n,variantId:o}]=e.args,a={currentState:t,recipeId:r,widgetId:n,variantId:o};await P(a),delete v[n]}e.reply({success:[]})},k=async e=>{if(H)try{const t=await H.apply(void 0,e.args);return e.reply({success:[t]})}catch(t){const r="string"==typeof t?t:JSON.stringify(t);return y(`Error invoking UI Event handler: ${r}`),e.reply({error:r})}e.reply({error:"UI Events are not supported in this service."})},z=async e=>{if(!o.eventEmitter)throw new Error("This service does not support broadcasting events. Please set `eventEmitter` to true in your manifest file.");if(n)return K.execute(a.KemuHubFunctions.BroadcastEvent,e,g.default.sendBuffer,n,u.KemuHubServiceId,{async:!0});y("Service session id is not set. Cannot broadcast event.")};t.broadcast=async(e,t)=>{const r=[{outputs:e,variantId:t}];await z(r)},t.broadcastEvent=async e=>{const t=[{outputs:e.outputs,variantId:e.variantId,eventContext:e.eventContext,targetRecipeId:e.targetRecipeId,targetWidgetId:e.targetWidgetId}];await z(t)},t.addDependencyPath=async(e,t,r)=>{if(!n)throw new Error("Not yet registered with the Hub");const o=v[r];if(!o.currentSourceServiceId||!o.currentRecipeId)throw new Error("Cannot invoke this method before initialization");const i={key:e,path:t,recipeId:o.currentRecipeId,widgetId:r};y(`Adding dependency path for key "${e}" with path "${t}"`),await K.execute(a.ServiceToServiceFunctions.SetDependencyPath,[i],g.default.sendBuffer,n,o.currentSourceServiceId)},t.getDependencyPath=async(e,t)=>{if(!n)throw new Error("Not yet registered with the Hub");const r=v[t];if(!r.currentSourceServiceId||!r.currentRecipeId)throw new Error("Cannot invoke this method before initialization");y("Getting dependency path for key:",e);const o={key:e,recipeId:r.currentRecipeId,widgetId:t},[i]=await K.execute(a.ServiceToServiceFunctions.GetDependencyPath,[o],g.default.sendBuffer,n,r.currentSourceServiceId);return y("Dependency path response:",i),i},t.getUniqueId=async()=>{if(!n)throw new Error("Not yet registered with the Hub");const[e]=await K.execute(a.KemuHubFunctions.GetUniqueId,[],g.default.sendBuffer,n,u.KemuHubServiceId);return e},t.resolveRuntimeDependencyPath=e=>{if(!S.recipePath)throw new Error("Cannot resolve runtime dependency without a recipe path. Missing [--recipePath] argument.");return d.default.resolve(S.recipePath,e)},t.onGetDefaultState=e=>{h=e},t.onParentEvent=e=>{b=e},t.onTerminate=e=>{P=e},t.onInitialize=e=>{w=e},t.onConnected=e=>{A=e},t.onStartBroadcast=e=>{I=e},t.onStopBroadcast=e=>{L=e},t.onUIEvent=e=>{H=e},S.internal&&(t.executeHubFunction=async(e,t,r)=>{if(n)return K.execute(e,t,g.default.sendBuffer,n,u.KemuHubServiceId,r);y("Service session id is not set. Cannot execute hub function.")});const D=t;return D._getRemoteInvoker=()=>K,D.getHubConfig=async()=>{if(!n)throw new Error("Service session id is not set. Cannot execute hub function.");const e=await K.execute(a.KemuHubFunctions.GetHubConfig,[],g.default.sendBuffer,n,u.KemuHubServiceId);return e?.[0]&&!e[0].kemuApiKey&&c&&(e[0].kemuApiKey=c),e?.[0]},D.getEdgeApiKey=async()=>{if(p)return void console.warn("This method [getEdgeApiKey] is NOT available in dev mode");if(!n)throw new Error("Service session id is not set. Cannot execute hub function.");const e=await K.execute(a.KemuHubFunctions.GetDecryptedEdgeApiKey,[],g.default.sendBuffer,n,u.KemuHubServiceId);return e?.[0]},t}}(s)),s));module.exports=se;
1
+ "use strict";var e=require("fs/promises"),t=require("minimist"),r=require("path"),n=require("node-ipc"),o=require("debug");function a(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var i,s={},c={},d={};var u,l={};var f,g={};var p,m={};var y,S={};var v,b={};var I,h,L={};function w(){return h||(h=1,e=c,H=c&&c.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),A=c&&c.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||H(t,e,r)},Object.defineProperty(e,"__esModule",{value:!0}),A((i||(i=1,Object.defineProperty(d,"__esModule",{value:!0}),d.DataTypeStr=d.DataType=d.RecipeType=void 0,function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}(t||(d.RecipeType=t={})),function(e){e[e.Number=0]="Number",e[e.String=1]="String",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Array=3]="Array",e[e.Boolean=4]="Boolean",e[e.JsonObj=5]="JsonObj",e[e.Anything=6]="Anything",e[e.ImageData=7]="ImageData",e[e.AudioBuffer=8]="AudioBuffer",e[e.Rect=9]="Rect",e[e.Point=10]="Point",e[e.ImageBitmap=11]="ImageBitmap",e[e.BinaryFile=12]="BinaryFile"}(r||(d.DataType=r={})),function(e){e.Number="Number",e.String="String",e.ArrayBuffer="ArrayBuffer",e.Array="Array",e.Boolean="Boolean",e.JsonObj="JsonObj",e.Anything="Anything",e.ImageData="ImageData",e.AudioBuffer="AudioBuffer",e.Rect="Rect",e.Point="Point",e.ImageBitmap="ImageBitmap",e.BinaryFile="BinaryFile"}(n||(d.DataTypeStr=n={}))),d),e),A((u||(u=1,Object.defineProperty(l,"__esModule",{value:!0})),l),e),A((f||(f=1,Object.defineProperty(g,"__esModule",{value:!0})),g),e),A((p||(p=1,Object.defineProperty(m,"__esModule",{value:!0}),m.ProcessorType=void 0,function(e){e.Javascript="js",e.Python="py",e.Executable="exe"}(o||(m.ProcessorType=o={}))),m),e),A((y||(y=1,Object.defineProperty(S,"__esModule",{value:!0}),S.Transport=S.ServiceToServiceFunctions=S.KemuHubFunctions=S.KemuHubCommand=void 0,function(e){e.IpcAcknowledge="iack:",e.SocketAcknowledge="sack:",e.AcknowledgeResponse="ackr:",e.ServicesListChanged="update-services",e.SendManifest="send-manifest",e.BroadcastStart="broadcast-start",e.BroadcastEnd="broadcast-end",e.AssumeSession="assume:"}(a||(S.KemuHubCommand=a={})),function(e){e.GetServices="getServices",e.SubscribeToService="subscribeToService",e.UnsubscribeFromService="unsubscribeFromService",e.GetServiceContents="getServiceContents",e.SocketAckResponse="socketAckResponse",e.ShowSecretsConfigScreen="showSecretsConfigScreen",e.GetMappedSecrets="getMappedSecrets",e.GetSecretContexts="getSecretContexts",e.OnParentEvent="onParentEvent",e.GetDefaultState="getDefaultState",e.BroadcastEvent="broadcastEvent",e.HubBroadcastEvent="hubBroadcastEvent",e.ServiceManifest="serviceManifest",e.SendToRecipe="sendToRecipe",e.KemuComposerDisconnected="kemu-composer-disconnected",e.GetState="getState",e.SetState="setState",e.SetOutputs="setOutputs",e.UIEvent="uiEvent",e.GetSystemInfo="getSystemInfo",e.InitializeInstance="initializeInstance",e.TerminateInstance="terminateInstance",e.UninstallService="uninstallService",e.ChooseDirectoryDialog="chooseDirectoryDialog",e.ChooseFileDialog="chooseFileDialog",e.GetUniqueId="getUniqueId",e.RebootToInstallUpdate="rebootToInstallUpdate",e.GetFileContentFromCacheId="getFileContentFromCacheId",e.GetDecryptedEdgeApiKey="getDecryptedEdgeApiKey",e.GetHubConfig="getHubConfig",e.GetRecipeDecryptedSecretsValues="getRecipeDecryptedSecretsValues",e.GetRecipeSecretMappings="getRecipeSecretMappings",e.AddRecipeSecretMapping="addRecipeSecretMapping",e.DeleteRecipeSecretMapping="deleteRecipeSecretMapping",e.GetHubSecrets="getHubSecrets",e.AddHubSecrets="addHubSecrets",e.DeleteHubSecret="deleteHubSecret"}(s||(S.KemuHubFunctions=s={})),function(e){e.SetDependencyPath="setDependencyPath",e.GetDependencyPath="getDependencyPath"}(w||(S.ServiceToServiceFunctions=w={})),function(e){e.IPC="ipc",e.WS="ws"}(P||(S.Transport=P={}))),S),e),A((v||(v=1,Object.defineProperty(b,"__esModule",{value:!0})),b),e),A((I||(I=1,Object.defineProperty(L,"__esModule",{value:!0})),L),e)),c;var e,t,r,n,o,a,s,w,P,H,A}var P,H={};var A,K={};function C(){if(A)return K;A=1,Object.defineProperty(K,"__esModule",{value:!0}),K.onAssumeSession=K.buildIpcAckResponse=K.isBrowser=K.onSendManifestCommand=K.onEndBroadcastCommand=K.onStartBroadcastCommand=K.onAckResponse=K.onAckRequest=K.buildSocketAckRequest=K.buildIpcAckRequest=K.buildAckResponse=K.safeJsonParse=void 0;const e=w();K.safeJsonParse=e=>{try{return JSON.parse(e)}catch(e){return null}};K.buildAckResponse=t=>`${e.KemuHubCommand.AcknowledgeResponse}${t}`;K.buildIpcAckResponse=(t,r)=>`${e.KemuHubCommand.AcknowledgeResponse}${t}:${r||""}`;K.buildIpcAckRequest=()=>`${e.KemuHubCommand.IpcAcknowledge}`;K.buildSocketAckRequest=t=>`${e.KemuHubCommand.SocketAcknowledge}${t}`;K.onAssumeSession=(t,r)=>{if(t.startsWith(e.KemuHubCommand.AssumeSession)){const n=t.split(e.KemuHubCommand.AssumeSession);return r(parseInt(n[1])),!0}return!1};K.onAckResponse=(t,r)=>{if(t.startsWith(e.KemuHubCommand.AcknowledgeResponse)){const n=t.split(e.KemuHubCommand.AcknowledgeResponse),o=parseInt(n[1]);return r&&r(o),o}return null};K.onAckRequest=(t,r)=>{const n=e.KemuHubCommand.SocketAcknowledge,o=e.KemuHubCommand.IpcAcknowledge,a=t.startsWith(n),i=t.startsWith(o);if(a||i){const e=t.split(a?n:o),i=parseInt(e[1]);return r&&r(i),i}return null};K.onStartBroadcastCommand=(t,r)=>t===e.KemuHubCommand.BroadcastStart&&(r(),!0);K.onEndBroadcastCommand=(t,r)=>t===e.KemuHubCommand.BroadcastEnd&&(r(),!0);K.onSendManifestCommand=(t,r)=>t===e.KemuHubCommand.SendManifest&&(r(),!0);const t="undefined"!=typeof window;return K.isBrowser=t,K}var B,D={};var E,_={},j={};var k,M={},z={},U={};function R(){return k||(k=1,e=U,Object.defineProperty(e,"__esModule",{value:!0}),e.KLCmdHeaderSize=e.KLHeaderSize=e.KLCmdProtocolHeaderSize=e.KLProtocolHeadersSize=void 0,e.KLProtocolHeadersSize={protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8},e.KLCmdProtocolHeaderSize={protocolPrefix:4,txtLength:4},e.KLHeaderSize=Object.values(e.KLProtocolHeadersSize).reduce(((e,t)=>e+t),0),e.KLCmdHeaderSize=Object.values(e.KLCmdProtocolHeaderSize).reduce(((e,t)=>e+t),0)),U;var e}var O,x={};function T(){if(O)return x;O=1,Object.defineProperty(x,"__esModule",{value:!0}),x.setNestedProperty=x.decodeMap=x.isSupportedBinaryType=x.getEncodedMap=void 0;const e=["width","height","colorSpace"],t=e=>{const t="undefined"!=typeof Buffer&&e instanceof Buffer,r=e instanceof ArrayBuffer,n=e instanceof Uint8ClampedArray,o=e instanceof Uint8Array,a=e instanceof Int8Array;return t?"Buffer":r?"ArrayBuffer":n?"Uint8ClampedArray":o?"Uint8Array":a?"Int8Array":null};x.isSupportedBinaryType=t;x.getEncodedMap=(r,n)=>{const o={},a=[];let i=0,s=Array.isArray(r)?[]:{};const c=(r,s)=>{const d=t(r);if(!d){if(Array.isArray(r)){const e=[];for(let t=0;t<r.length;t++)e[t]=c(r[t],`${s}[${t}]`);return e}if("object"==typeof r){const t={},n=(e=>{const t=e instanceof Int16Array,r=e instanceof Uint16Array,n=e instanceof Int32Array,o=e instanceof Uint32Array,a=e instanceof Float32Array,i=e instanceof Float64Array,s=e instanceof BigInt64Array,c=e instanceof BigUint64Array;return t?"Int16Array":r?"Uint16Array":n?"Int32Array":o?"Uint32Array":a?"Float32Array":i?"Float64Array":s?"BigInt64Array":c?"BigUint64Array":null})(r);if(n)throw new Error(`Unsupported binary type [${n}] at path "${s}"`);for(const n in r)Object.hasOwn(r,n)||e.includes(n)||console.warn(`Allowing inherited property: ${n} from path: ${s}`),t[n]=c(r[n],`${s.length?`${s}.`:""}${n}`);return t}return r}o[s]={index:i,length:r.byteLength,binaryType:d},"Buffer"===n?a.push(Buffer.from(r)):"ArrayBuffer"===d?a.push(r):a.push(r.buffer),i+=r.byteLength};s=c(r,"");let d=null;if(a.length>1)if("ArrayBuffer"===n){const e=a.reduce(((e,t)=>e+t.byteLength),0),t=new Uint8Array(e);let r=0;for(let e=0;e<a.length;e++)t.set(new Uint8Array(a[e]),r),r+=a[e].byteLength;d=t.buffer}else{d=Buffer.concat(a)}else 1===a.length&&(d=a[0]);return d?{map:o,combinedData:d,sourceCopy:s}:null};const r=(e,t,r,n)=>{const o=t.match(/(\[\d+\])|([^[\].]+)/g)||[];let a=e;for(let e=0;e<o.length;e++){let t=o[e];const i=t.startsWith("[")&&t.endsWith("]"),s=e===o.length-1;if(i){t=t.slice(1,-1);const i=parseInt(t,10);if(!Array.isArray(a))throw new Error(`Expected an array at key "${o.slice(0,e).join(".")}" but found an object.`);s?n?a.splice(i,1):a[i]=r:(a[i]||(a[i]=o[e+1].startsWith("[")?[]:{}),a=a[i])}else s?n?delete a[t]:a[t]=r:(a[t]||(a[t]=o[e+1].startsWith("[")?[]:{}),a=a[t])}return e};x.setNestedProperty=r;return x.decodeMap=(e,t,n)=>{const o="undefined"!=typeof Buffer,a=t instanceof Uint8Array;for(const i in n)if(Object.hasOwn(n,i)){const{index:s,length:c,binaryType:d}=n[i];let u=null;if(o&&t instanceof Buffer)switch(d){case"Buffer":u=t.subarray(s,s+c);break;case"ArrayBuffer":u=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(s,s+c);break;case"Uint8Array":u=new Uint8Array(t.subarray(s,s+c));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.subarray(s,s+c));break;case"Int8Array":u=new Int8Array(t.subarray(s,s+c))}else if(t instanceof ArrayBuffer||t instanceof Uint8Array)switch(d){case"Buffer":if(o){u=Buffer.from(t.slice(s,s+c));break}case"ArrayBuffer":u=a?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(s,s+c):t.slice(s,s+c);break;case"Uint8Array":u=a?t.slice(s,s+c):new Uint8Array(t.slice(s,s+c));break;case"Uint8ClampedArray":u=new Uint8ClampedArray(t.slice(s,s+c));break;case"Int8Array":u=new Int8Array(t.slice(s,s+c))}u&&r(e,i,u)}return e},x}var F,$,N={};function G(){if(F)return N;F=1;var e=N&&N.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(N,"__esModule",{value:!0}),N.createLogger=void 0;const t=e(o);return N.createLogger=e=>(0,t.default)(e),N}function V(){if($)return z;$=1,Object.defineProperty(z,"__esModule",{value:!0});const e=C(),t=R(),r=T(),n=G(),o="KMSG",a="KCMD",i=(0,n.createLogger)("klProtocol");return z.default={encode:(e,n,a)=>{const i={json:e.json},s=(0,r.getEncodedMap)(i.json,"Buffer"),c=s?.combinedData;s&&(i.jsonBinaryMap=s.map,i.json=s.sourceCopy);const d=c?c.byteLength:0,u=JSON.stringify(i),l=Buffer.from(u),f=l.byteLength,g=t.KLProtocolHeadersSize.protocolPrefix+t.KLProtocolHeadersSize.protocolVersion+t.KLProtocolHeadersSize.jsonLength+t.KLProtocolHeadersSize.binaryLength+t.KLProtocolHeadersSize.fromServiceId+t.KLProtocolHeadersSize.toServiceId+t.KLProtocolHeadersSize.sentAt+f+d,p=Buffer.alloc(g),m=Date.now();let y=0;return p.write(o,y),y+=t.KLProtocolHeadersSize.protocolPrefix,p.writeUInt8(1,y),y+=t.KLProtocolHeadersSize.protocolVersion,p.writeUInt32LE(f,y),y+=t.KLProtocolHeadersSize.jsonLength,p.writeUInt32LE(d,y),y+=t.KLProtocolHeadersSize.binaryLength,p.writeUInt32LE(n,y),y+=t.KLProtocolHeadersSize.fromServiceId,p.writeUInt32LE(a,y),y+=t.KLProtocolHeadersSize.toServiceId,p.writeBigInt64LE(BigInt(m),y),y+=t.KLProtocolHeadersSize.sentAt,l.copy(p,y),y+=f,c&&d&&c.copy(p,y),p},decodeHeader:e=>{let r=0;const n=e.toString("utf-8",r,t.KLProtocolHeadersSize.protocolPrefix);if(r+=t.KLProtocolHeadersSize.protocolPrefix,n!==o)return null;if(e.byteLength<t.KLHeaderSize)return i(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const a=e.readUInt8(r);r+=t.KLProtocolHeadersSize.protocolVersion;const s=e.readUInt32LE(r);r+=t.KLProtocolHeadersSize.jsonLength;const c=e.readUInt32LE(r);r+=t.KLProtocolHeadersSize.binaryLength;const d=e.readUInt32LE(r);r+=t.KLProtocolHeadersSize.fromServiceId;const u=e.readUInt32LE(r);r+=t.KLProtocolHeadersSize.toServiceId;const l=e.readBigInt64LE(r);r+=t.KLProtocolHeadersSize.sentAt;const f=s+c,g=e.subarray(r,r+f),p=e.subarray(0,t.KLHeaderSize);let m=null;return e.byteLength-t.KLHeaderSize-s-c>0&&(m=e.subarray(t.KLHeaderSize+s+c)),{header:{protocolVersion:a,jsonLength:s,binaryLength:c,fromServiceId:d,toServiceId:u,sentAt:new Date(Number(l)),packages:[g],headerPackage:p},remaining:m}},decodeFullKlMessage:n=>{const o=Buffer.concat(n.packages),a=o.subarray(0,n.jsonLength).toString(),s=o.subarray(n.jsonLength,n.jsonLength+n.binaryLength),c=(0,e.safeJsonParse)(a);if(!c?.json)return i("Invalid JSON in KL message"),null;c.jsonBinaryMap&&s.byteLength&&(0,r.decodeMap)(c.json,s,c.jsonBinaryMap);const d=Buffer.concat([n.headerPackage,o]);let u=d,l=null;const f=t.KLHeaderSize+n.jsonLength+n.binaryLength;return d.byteLength>f&&(l=d.subarray(f),u=d.subarray(0,f)),{message:{json:c.json,rawMessage:u},remaining:l}},patchEncodedHeader:(e,r)=>{if(null==r.fromServiceId&&void 0===r.toServiceId)return e;if(e.byteLength<t.KLHeaderSize)return i("Invalid Header Size"),e;let n=0;return n+=t.KLProtocolHeadersSize.protocolPrefix,n+=t.KLProtocolHeadersSize.protocolVersion,n+=t.KLProtocolHeadersSize.jsonLength,n+=t.KLProtocolHeadersSize.binaryLength,void 0!==r.fromServiceId&&e.writeUInt32LE(r.fromServiceId,n),n+=t.KLProtocolHeadersSize.fromServiceId,void 0!==r.toServiceId&&e.writeUInt32LE(r.toServiceId,n),e},encodeCommand:e=>{let r=0;const n=Buffer.from(e),o=n.byteLength,i=t.KLCmdHeaderSize+o,s=Buffer.alloc(i);return s.write(a,r),r+=t.KLCmdProtocolHeaderSize.protocolPrefix,s.writeUint32LE(o,r),r+=t.KLCmdProtocolHeaderSize.txtLength,n.copy(s,r),s},decodeCommand:e=>{let r=0;if(e.byteLength<t.KLCmdHeaderSize)return{command:null};const n=e.toString("utf-8",r,t.KLCmdProtocolHeaderSize.protocolPrefix);if(r+=t.KLCmdProtocolHeaderSize.protocolPrefix,n!==a)return{command:null};const o=e.readUInt32LE(r);r+=t.KLCmdProtocolHeaderSize.txtLength;const i=e.toString("utf-8",r,r+o),s=e.byteLength-t.KLCmdHeaderSize-o;let c=null;s>0&&(c=e.subarray(t.KLCmdHeaderSize+o));let d=0;return s<0&&(d=Math.abs(s)),{command:i,remainingData:c,missing:d}}},z}var W,q,J={};function Q(){if(W)return J;W=1,Object.defineProperty(J,"__esModule",{value:!0});const e=R(),t=G(),r=T(),n=C(),o="KMSG",a="KCMD",i=(0,t.createLogger)("klProtocol"),s=new TextEncoder;return J.default={encode:(t,n,a)=>{const i={json:t.json},c=(0,r.getEncodedMap)(t.json,"ArrayBuffer"),d=c?.combinedData;c&&(i.jsonBinaryMap=c.map,i.json=c.sourceCopy);const u=d?d.byteLength:0,l=JSON.stringify(i),f=s.encode(l),g=f.byteLength,p=e.KLProtocolHeadersSize.protocolPrefix+e.KLProtocolHeadersSize.protocolVersion+e.KLProtocolHeadersSize.jsonLength+e.KLProtocolHeadersSize.binaryLength+e.KLProtocolHeadersSize.fromServiceId+e.KLProtocolHeadersSize.toServiceId+e.KLProtocolHeadersSize.sentAt+g+u,m=new ArrayBuffer(p),y=new DataView(m),S=new Uint8Array(m),v=Date.now();let b=0;for(let e=0;e<4;++e)S[b++]=o.charCodeAt(e);return y.setUint8(b,1),b+=e.KLProtocolHeadersSize.protocolVersion,y.setUint32(b,g,!0),b+=e.KLProtocolHeadersSize.jsonLength,y.setUint32(b,u,!0),b+=e.KLProtocolHeadersSize.binaryLength,y.setUint32(b,n,!0),b+=e.KLProtocolHeadersSize.fromServiceId,y.setUint32(b,a,!0),b+=e.KLProtocolHeadersSize.toServiceId,y.setBigInt64(b,BigInt(v),!0),b+=e.KLProtocolHeadersSize.sentAt,S.set(f,b),b+=g,d&&u&&S.set(new Uint8Array(d),b),m},decodeHeader:t=>{const r=new DataView(t);let n=0,a="";for(let t=0;t<e.KLProtocolHeadersSize.protocolPrefix;++t)a+=String.fromCharCode(r.getUint8(n++));if(a!==o)return null;if(t.byteLength<e.KLHeaderSize)return i.log(`Received a Partial Header with ${t.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const s=r.getUint8(n);n+=e.KLProtocolHeadersSize.protocolVersion;const c=r.getUint32(n,!0);n+=e.KLProtocolHeadersSize.jsonLength;const d=r.getUint32(n,!0);n+=e.KLProtocolHeadersSize.binaryLength;const u=r.getUint32(n,!0);n+=e.KLProtocolHeadersSize.fromServiceId;const l=r.getUint32(n,!0);n+=e.KLProtocolHeadersSize.toServiceId;const f=r.getBigInt64(n,!0);n+=e.KLProtocolHeadersSize.sentAt;const g=c+d,p=t.slice(n,n+g),m=new Uint8Array(t,0,e.KLHeaderSize);let y=null;if(t.byteLength-e.KLHeaderSize-c-d>0){y=new Uint8Array(t,e.KLHeaderSize+c+d).slice().buffer}return{header:{protocolVersion:s,jsonLength:c,binaryLength:d,fromServiceId:u,toServiceId:l,sentAt:new Date(Number(f)),packages:[p],headerPackage:m.slice().buffer},remaining:y}},decodeFullKlMessage:t=>{const o=t.packages.reduce(((e,t)=>e+t.byteLength),0),a=new Uint8Array(o);let s,c=0;for(const e of t.packages)s=new Uint8Array(e),a.set(s,c),c+=s.byteLength;const d=(new TextDecoder).decode(a.subarray(0,t.jsonLength)),u=a.subarray(t.jsonLength,t.jsonLength+t.binaryLength),l=(0,n.safeJsonParse)(d);if(!l?.json)return i.log("Invalid JSON in KL message"),null;l.jsonBinaryMap&&u.byteLength&&(0,r.decodeMap)(l.json,u,l.jsonBinaryMap);const f=new Uint8Array(t.headerPackage.byteLength+a.byteLength);f.set(new Uint8Array(t.headerPackage),0),f.set(a,t.headerPackage.byteLength);let g=f,p=null;const m=e.KLHeaderSize+t.jsonLength+t.binaryLength;return f.byteLength>m&&(p=f.subarray(m),g=f.subarray(0,m)),{message:{json:l.json,...u.length?{binaryData:u.buffer}:{},rawMessage:g.buffer},remaining:p?.buffer??null}},patchEncodedHeader:(t,r)=>{if(null==r.fromServiceId&&void 0===r.toServiceId)return t;if(t.byteLength<e.KLHeaderSize)return i("Invalid Header Size"),t;let n=0;n+=e.KLProtocolHeadersSize.protocolPrefix,n+=e.KLProtocolHeadersSize.protocolVersion,n+=e.KLProtocolHeadersSize.jsonLength,n+=e.KLProtocolHeadersSize.binaryLength;const o=new DataView(t);return void 0!==r.fromServiceId&&o.setUint32(n,r.fromServiceId,!0),n+=e.KLProtocolHeadersSize.fromServiceId,void 0!==r.toServiceId&&o.setUint32(n,r.toServiceId,!0),t},encodeCommand:t=>{let r=0;const n=s.encode(t),o=n.byteLength,i=e.KLCmdHeaderSize+o,c=new ArrayBuffer(i),d=new DataView(c),u=new Uint8Array(c);for(let e=0;e<4;++e)u[r++]=a.charCodeAt(e);return d.setUint32(r,o,!0),r+=e.KLCmdProtocolHeaderSize.txtLength,u.set(n,r),c},decodeCommand:t=>{const r=new DataView(t);let n=0;if(t.byteLength<e.KLCmdHeaderSize)return{command:null};let o="";for(let t=0;t<e.KLCmdProtocolHeaderSize.protocolPrefix;++t)o+=String.fromCharCode(r.getUint8(n++));if(o!==a)return{command:null};const i=r.getUint32(n,!0);n+=e.KLCmdProtocolHeaderSize.txtLength;const s=t.byteLength-e.KLCmdHeaderSize-i,c=new Uint8Array(t,n,Math.min(i,t.byteLength-e.KLCmdHeaderSize)),d=(new TextDecoder).decode(c);let u=null;s>0&&(u=t.slice(e.KLCmdHeaderSize+i));let l=0;return s<0&&(l=Math.abs(s)),{command:d,remainingData:u,missing:l}}},J}function X(){if(q)return M;q=1;var e=M&&M.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(M,"__esModule",{value:!0}),M.createTransmissionManager=void 0;const t=e(V()),r=e(Q()),n=(0,G().createLogger)("klTransmissionManager");return M.createTransmissionManager=()=>{const e=(o,a,i,s)=>{let c=a,d=null;const u=o instanceof ArrayBuffer;if(n(`RAW: ${o.toString()}`),!c||c.partialHeaderData){let l;if(u?(l=c?.partialHeaderData?new Uint8Array([...new Uint8Array(c.partialHeaderData),...new Uint8Array(o)]).buffer:o,d=r.default.decodeHeader(l)):(l=c?.partialHeaderData?Buffer.concat([c.partialHeaderData,o]):o,d=t.default.decodeHeader(l)),!d){const{command:o,missing:c,remainingData:d}=u?r.default.decodeCommand(l):t.default.decodeCommand(l);return o?s({command:o,complete:!0,rawMessage:l}):n(c?`ERROR: Missing ${c} bytes to complete the command. This partial command will be aborted.`:`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${l.byteLength} bytes`),d?(n(`${d.byteLength} bytes remain after processing command. Re-analyzing...`),e(d,a,i,s)):void 0}if(d.partialHeader)return c={firstPackageAt:Date.now(),partialHeaderData:l},i(c);if(!d.header)return n(`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${l.byteLength} bytes`);const f=d.header;c={firstPackageAt:Date.now(),header:{...f,totalBytesReceived:f.packages[0].byteLength,totalBytesExpected:f.binaryLength+f.jsonLength,remaining:d.remaining}},i(c)}else c.header&&c.header.totalBytesReceived<c.header.totalBytesExpected&&(c.header.packages.push(o),c.header.totalBytesReceived+=o.byteLength,i(c));if(c.header&&c.header.totalBytesReceived>=c.header.totalBytesExpected){const o=Date.now()-c.header.sentAt.getTime(),a=Date.now()-c.firstPackageAt;n(`Received ${c.header.totalBytesReceived} of ${c.header.totalBytesExpected} expected in ${o} ms, elapsed since first package: ${a}ms`);const d=u?r.default.decodeFullKlMessage(c.header):t.default.decodeFullKlMessage(c.header),l=c.header.totalBytesReceived,f=c.header.remaining;i(null),d&&s({klMessage:d.message,complete:!0,sourceServiceId:c.header.fromServiceId,targetServiceId:c.header.toServiceId,rawMessage:d.message.rawMessage});let g=f;if(d?.remaining&&(g=u?f?((e,t)=>{const r=e.byteLength+t.byteLength,n=new ArrayBuffer(r),o=new Uint8Array(e),a=new Uint8Array(t),i=new Uint8Array(n);return i.set(o),i.set(a,o.length),n})(f,d.remaining):d.remaining:f?Buffer.concat([f,d.remaining]):d.remaining),g)return n(`${g.byteLength} bytes remaining after processing message with ${l} bytes of data. Re-analyzing...`),e(g,null,i,s)}};return e},M}var Y,Z,ee={};function te(){if(Y)return ee;Y=1;var e=ee&&ee.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(ee,"__esModule",{value:!0});const t=e(V()),r=e(Q()),n=C();let o=t.default;return n.isBrowser&&(o=r.default),ee.default=o,ee}function re(){if(Z)return _;Z=1;var e=_&&_.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0});const t=e(n),r=e((E||(E=1,Object.defineProperty(j,"__esModule",{value:!0}),j.default={id:"widgets",retry:1500,silent:!0,rawBuffer:!0,appspace:"kemu.",encoding:"hex"}),j)),o=X(),a=G(),i=e(te());let s,c,d,u,l=null;const f=(0,o.createTransmissionManager)(),g=(0,a.createLogger)("ipcClient"),p=e=>{const n=r.default.id;t.default.of[n].emit(e)};return _.default={connect:e=>{r.default.id=e?.id||r.default.id,r.default.appspace=e?.appSpace||r.default.appspace,t.default.config={...t.default.config,...r.default};const n=r.default.id;t.default.connectTo(n,(()=>{t.default.of[n].on("connect",(()=>{g("Connected to server"),l=null,c&&c()})),t.default.of[n].on("data",(e=>{f(e,l,(e=>l=e),(e=>{if(e.complete)return e.command?(g(`Received command: ${e.command}`),void(s&&s(e.command))):void(e.klMessage&&d&&d({send:p,transmission:{sourceServiceId:e.sourceServiceId??-1,targetServiceId:e.targetServiceId??-1,rawMessage:e.rawMessage},json:e.klMessage.json}))}))})),t.default.of[n].on("disconnect",(()=>{g(`Disconnected from ${n}`),l=null,u&&u()}))}))},sendCommand:e=>{const n=r.default.id,o=i.default.encodeCommand(e);t.default.of[n].emit(o)},sendBuffer:p,onCommand:e=>s=e,onMessageReceived:e=>d=e,onClientConnected:e=>c=e,onClientDisconnected:e=>u=e},_}var ne,oe,ae,ie={},se={};function ce(){return oe||(oe=1,function(e){var t=ie&&ie.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),r=ie&&ie.__exportStar||function(e,r){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(r,n)||t(r,e,n)},n=ie&&ie.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0});const o=n(te()),a=C();var i;r((ne||(ne=1,Object.defineProperty(se,"__esModule",{value:!0}),se.RemoveInvokeError=void 0,function(e){e.FunctionNotFound="FNC_NOT_FOUND",e.ParentEventCallbackError="PARENT_EVENT_CALLBACK_ERROR"}(i||(se.RemoveInvokeError=i={}))),se),e);let s=Math.ceil(Date.now()/1e3);e.default=function(e){const t={};let r=console.log;const n={};let i=e||String(Date.now());const c={},d=e=>!c[e],u=(e,t,r,n,i,s)=>{let c=a.isBrowser?new ArrayBuffer(0):Buffer.alloc(0);const u={json:{functionName:e,args:s.success?s.success:[s],messageId:t,type:s.success?"response":"error"}};return d(n)&&(c=o.default.encode(u,r,n)),i(c,{msg:u,sourceServiceId:r,targetServiceId:n})};return{setLogger:e=>{r=e},processMessage:(e,o,a,i)=>{if(!i)return!1;const s=i;if(t[s.messageId]){const e=t[s.messageId];return e&&(clearTimeout(e.timer),e.fulfilled||(e.fulfilled=!0,"response"===s.type?e.resolve(s.args):"error"===s.type&&e.reject(s.args[0])),delete t[s.messageId]),!0}if("execute"!==s.type&&r&&r(`No pending execution found for message id "${s.messageId}"`),"execute"===s.type){const t=n[s.functionName];if(t){const r=e=>{u(s.functionName,s.messageId,a.targetServiceId,a.sourceServiceId,o,e)};t({transport:e,args:s.args,reply:r,messageId:s.messageId,sourceServiceId:a.sourceServiceId,send:o})}else{const e=`Function "${s.functionName}" not found.`;r&&r(e),u(s.functionName,s.messageId,a.targetServiceId,a.sourceServiceId,o,{error:e,errCode:"FNC_NOT_FOUND"})}return!0}return!1},execute:async(e,n,c,u,l,f)=>{if(!c){const e="No send buffer function provided.";throw r&&r(e),e}s+=1;const g=`${i}-${s}-exec-${e.substring(0,10)}`,p={messageId:g,functionName:e,send:c,sourceServiceId:u,targetServiceId:l,args:n||[],fulfilled:!1,resolve:()=>{},reject:()=>{}};p.promise=new Promise(((e,t)=>{p.resolve=e,p.reject=t}));let m=a.isBrowser?new ArrayBuffer(0):Buffer.alloc(0);const y={json:{functionName:e,args:n,messageId:g,type:"execute"}};d(l)&&(m=o.default.encode(y,u,l)),t[g]=p,r&&r(`Calling remote function "${e}" with message id "${g}"`);const S="true"===process.env.NO_INVOKE_TIMEOUT;return f?.async?(p.fulfilled=!0,p.resolve([void 0]),delete t[g]):0===f?.timeout||S||(p.timer=setTimeout((()=>{r&&r(`Remote function ${g} timed out`);const n=t[g];n&&!n.fulfilled&&(n.fulfilled=!0,p.reject(`Function ${e} Timed out`)),delete t[g]}),f?.timeout||3e4)),c(m,{sourceServiceId:u,targetServiceId:l,msg:y}),p.promise},sendResponse:u,registerFunction:(e,t)=>{n[e]=t},getTransportSendFunction:e=>{const r=t[e];return r?r.send:null},setServiceName:e=>{i=e},getPendingExecutions:()=>t,rejectAllPending:e=>{Object.keys(t).forEach((r=>{const n=t[r];n&&!n.fulfilled&&(clearTimeout(n.timer),n.fulfilled=!0,n.reject(e),delete t[r])}))},broadcast:(e,t,n,c)=>{s+=1;const u=`${i}-${s}-multicast-${e.substring(0,10)}`;let l=a.isBrowser?new ArrayBuffer(0):Buffer.alloc(0);const f={json:{functionName:e,args:t,messageId:u,type:"execute"}};let g=d(n[0].serviceId);g&&(l=o.default.encode(f,c,n[0].serviceId));for(let t=0;t<n.length;t++)try{const a=n[t];r&&r(`Broadcasting function "${e}" with message id "${u}" to client [${a.serviceId}]`),0!==t&&(g=d(a.serviceId),g&&(l=o.default.patchEncodedHeader(l,{toServiceId:a.serviceId}))),a.sendFn(l,{msg:f,sourceServiceId:c,targetServiceId:a.serviceId})}catch(e){r&&r(`Error broadcasting to client at index ${t}`)}},disableServiceEncoding:(e,t)=>{c[e]=t}}}}(ie)),ie}var de=a((ae||(ae=1,function(n){var o=s&&s.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(n,"__esModule",{value:!0}),n.createImageDataLike=n.KemuHubServiceId=n.DataType=void 0;const a=w();Object.defineProperty(n,"DataType",{enumerable:!0,get:function(){return a.DataType}});const i=e,c=o(t),d=o(r),u=(P||(P=1,Object.defineProperty(H,"__esModule",{value:!0}),H.KemuHubServiceId=void 0,H.KemuHubServiceId=0),H);Object.defineProperty(n,"KemuHubServiceId",{enumerable:!0,get:function(){return u.KemuHubServiceId}});const l=C(),f=function(){if(B)return D;B=1,Object.defineProperty(D,"__esModule",{value:!0}),D.preProcessManifest=D.portStrToWidgetPort=D.createImageDataLike=void 0;const e=w();return D.createImageDataLike=(t,r,n,o="srgb")=>{let a;return a=t instanceof Uint8ClampedArray?t:new Uint8ClampedArray(t),{data:a,width:r,height:n,colorSpace:o,_kemuType:e.DataType.ImageData}},D.portStrToWidgetPort=t=>({...t,type:e.DataType[t.type]}),D.preProcessManifest=(e,t,r)=>({...e,path:t,...e.widgetUI&&r?.widgetUIContents?{widgetUIContents:r.widgetUIContents}:{}}),D}();Object.defineProperty(n,"createImageDataLike",{enumerable:!0,get:function(){return f.createImageDataLike}});const g=o(re()),p=G(),m=o(ce()),y=(0,p.createLogger)("kemuWidgetService"),S=(0,c.default)(process.argv.slice(2));n.default=function(e){const t={},r=process.env.KEMU_WIDGET_SESSION_ID;let n,o,s,c,p=!1;const v={};let b,I,h,L,w,P,H,A,K=null;const C=new m.default;C.setLogger(y),t.start=async(t,c)=>{const u=t||d.default.resolve(d.default.dirname(process.argv[1]),"manifest.json");s=d.default.dirname(u);const m=await(0,i.readFile)(u,"utf-8"),v=(0,l.safeJsonParse)(m);if(!v)throw new Error("Error parsing manifest file.");let b;if(v.inputs||(v.inputs=[]),v.outputs||(v.outputs=[]),v.widgetUI)try{b=await(0,i.readFile)(d.default.join(s,"widgetUI.js"))}catch(e){y(`Error loading widgetUI file ${v.name}: ${e}`)}if(v.svgIcon)try{const e=await(0,i.readFile)(d.default.join(s,v.svgIcon),"utf-8");v.svgIcon=e}catch(e){y(`Error loading icon for service ${v.name}: ${e}`)}o=(0,f.preProcessManifest)(v,s,{widgetUIContents:b}),p=o.name.startsWith("test."),o.path=s,o.internal=S.internal||!1,p?y("Starting Kemu Service in Dev mode"):((e=>{const t=e||S.sessionId||r;if(!t)throw new Error("Missing sessionId. Expected service to be launched with a sessionId as first argument, or the KEMU_WIDGET_SESSION_ID environment variable to be set.");n=parseInt(String(t))})(c),y(`Starting Kemu Service with session id: ${n}`)),C.setServiceName(`${o.name}_${o.version}`),g.default.onCommand(B),g.default.onMessageReceived((({json:e,transmission:t})=>C.processMessage(a.Transport.IPC,g.default.sendBuffer,t,e))),C.registerFunction(a.KemuHubFunctions.OnParentEvent,E),C.registerFunction(a.KemuHubFunctions.GetDefaultState,D),C.registerFunction(a.KemuHubFunctions.UIEvent,M),C.registerFunction(a.KemuHubFunctions.InitializeInstance,_),C.registerFunction(a.KemuHubFunctions.TerminateInstance,j),C.registerFunction(a.KemuHubFunctions.KemuComposerDisconnected,k),g.default.onClientConnected((()=>{A&&A()})),g.default.onClientDisconnected((()=>{p&&(n=void 0)})),g.default.connect({appSpace:S.ipcSpace||e?.ipc?.appSpace,id:S.ipcId||e?.ipc?.id})};const B=e=>{(0,l.onAckRequest)(e,(e=>{g.default.sendCommand((0,l.buildIpcAckResponse)(e,n||void 0)),!n&&p&&(y("Dev mode detected, assuming service session id from ack request:",e),n=e)})),(0,l.onStartBroadcastCommand)(e,(()=>{h&&h()})),(0,l.onEndBroadcastCommand)(e,(()=>{L&&L()})),(0,l.onSendManifestCommand)(e,(()=>{y("Sending manifest to hub"),n?C.execute(a.KemuHubFunctions.ServiceManifest,[{...o,devMode:p}],g.default.sendBuffer,n,u.KemuHubServiceId,{async:!0}):y("Service session id is not set. Cannot send manifest.")})),(0,l.onAssumeSession)(e,(e=>{n=e,y(`Assumed session id ${e}`)}))},D=async e=>{if(I){const t=await I();return e.reply({success:[t]})}return e.reply({success:[{}]})},E=async e=>{if(!b)return y("No onParentEvent callback defined. Skipping parent event."),e.reply({success:[]});const t=e.args[0],{source:r,target:o,data:i,recipe:s,currentState:c,targetVariantId:d,eventContext:u,currentPath:l,eventId:f}=t;if(!n)return void y("Service session id is not set. Cannot process parent event.");if(!r||!o||!i)return e.reply({error:"Invalid arguments, expected [source, target, data, context]"});const p=g.default.sendBuffer,m=async t=>C.execute(a.KemuHubFunctions.SetOutputs,[t],p,n,e.sourceServiceId,{timeout:0}),S={currentState:c,type:o.widgetType,widgetId:o.widgetId,variantId:d,recipeId:s.poolId,recipeName:s.name,recipe:s,setState:async t=>{const r={widgetId:o.widgetId,variantId:d,recipeId:s.poolId,newState:t};return C.execute(a.KemuHubFunctions.SetState,[r],p,n,e.sourceServiceId)},setOutputs:async(e,t)=>{const r={widgetId:o.widgetId,recipeId:s.poolId,outputs:e,finalState:t,currentPath:l};await m(r)},setOutputsWithContext:async e=>{const t={...e,widgetId:o.widgetId,recipeId:s.poolId,currentPath:l};await m(t)}};y(`Invoking user-defined onParentEvent callback for event id "${e.messageId}"`),await b({data:i,source:r,target:o,eventContext:u,currentPath:l,eventId:f},S).then((()=>{y(`Replying SUCCESS to event id "${e.messageId}"`),e.reply({success:[]})})).catch((t=>{const r="string"==typeof t?t:t.message||t;y(`Error invoking onParentEvent callback: ${r}`),e.reply({error:r,errCode:"PARENT_EVENT_CALLBACK_ERROR"})}))},_=async e=>{const[{currentState:t,widgetId:r,variantId:n,recipeType:o,currentDependencies:a,kemuApiKey:i,recipe:s}]=e.args;if(i&&(c=i),v[r]={currentRecipeId:s.poolId,variantId:n,currentSourceServiceId:e.sourceServiceId},w){const c=[],d={currentState:t,recipeId:s.poolId,recipeName:s.name,recipe:{uuid:s.uuid,poolId:s.poolId,name:s.name,type:s.type,version:s.version,authorId:s.authorId,dbId:s.dbId},widgetId:r,variantId:n,recipeType:o,currentDependencies:a||{},kemuApiKey:i,secrets:{requestAccess:e=>{c.push(...e)}}},u=await w(d);e.reply({success:[u,c]})}else e.reply({error:"Not implemented",errCode:"FNC_NOT_FOUND"})},j=async e=>{if(P){const[{currentState:t,recipe:r,widgetId:n,variantId:o}]=e.args,a={currentState:t,recipeId:r.poolId,recipe:r,widgetId:n,variantId:o};await P(a),delete v[n]}e.reply({success:[]})},k=async e=>{if(console.log("Kemu Composer disconnected event: ",e),e.reply({success:[]}),H){const[t]=e.args;t.recipe&&await H(t)}},M=async e=>{if(K)try{const t=await K.apply(void 0,e.args);return e.reply({success:[t]})}catch(t){const r="string"==typeof t?t:JSON.stringify(t);return y(`Error invoking UI Event handler: ${r}`),e.reply({error:r})}e.reply({error:"UI Events are not supported in this service."})},z=async e=>{if(!o.eventEmitter)throw new Error("This service does not support broadcasting events. Please set `eventEmitter` to true in your manifest file.");if(n)return C.execute(a.KemuHubFunctions.BroadcastEvent,e,g.default.sendBuffer,n,u.KemuHubServiceId,{async:!0});y("Service session id is not set. Cannot broadcast event.")};t.broadcast=async(e,t)=>{const r=[{outputs:e,variantId:t,currentPath:[]}];await z(r)},t.broadcastEvent=async e=>{const t=[{outputs:e.outputs,variantId:e.variantId,eventContext:e.eventContext,targetRecipeId:e.targetRecipeId,targetRecipePoolId:e.targetRecipePoolId,targetWidgetId:e.targetWidgetId,currentPath:e.currentPath||[],eventId:e.eventId}];await z(t)},t.addDependencyPath=async(e,t,r)=>{if(!n)throw new Error("Not yet registered with the Hub");const o=v[r];if(!o.currentSourceServiceId||!o.currentRecipeId)throw new Error("Cannot invoke this method before initialization");const i={key:e,path:t,recipeId:o.currentRecipeId,widgetId:r};y(`Adding dependency path for key "${e}" with path "${t}"`),await C.execute(a.ServiceToServiceFunctions.SetDependencyPath,[i],g.default.sendBuffer,n,o.currentSourceServiceId)},t.getDependencyPath=async(e,t)=>{if(!n)throw new Error("Not yet registered with the Hub");const r=v[t];if(!r.currentSourceServiceId||!r.currentRecipeId)throw new Error("Cannot invoke this method before initialization");y("Getting dependency path for key:",e);const o={key:e,recipeId:r.currentRecipeId,widgetId:t},[i]=await C.execute(a.ServiceToServiceFunctions.GetDependencyPath,[o],g.default.sendBuffer,n,r.currentSourceServiceId);return y("Dependency path response:",i),i},t.getUniqueId=async()=>{if(!n)throw new Error("Not yet registered with the Hub");const[e]=await C.execute(a.KemuHubFunctions.GetUniqueId,[],g.default.sendBuffer,n,u.KemuHubServiceId);return e},t.resolveRuntimeDependencyPath=e=>{if(!S.recipePath)throw new Error("Cannot resolve runtime dependency without a recipe path. Missing [--recipePath] argument.");return d.default.resolve(S.recipePath,e)},t.onGetDefaultState=e=>{I=e},t.onParentEvent=e=>{b=e},t.onTerminate=e=>{P=e},t.onKemuComposerDisconnected=e=>{H=e},t.onInitialize=e=>{w=e},t.onConnected=e=>{A=e},t.onStartBroadcast=e=>{h=e},t.onStopBroadcast=e=>{L=e},t.onUIEvent=e=>{K=e},t.secrets={read:async e=>{if(!n)throw new Error("Service session id is not set. Cannot read secret.");const t=[{recipeUuid:e.recipeUuid,secretNames:e.names}],[r]=await C.execute(a.KemuHubFunctions.GetRecipeDecryptedSecretsValues,t,g.default.sendBuffer,n,u.KemuHubServiceId);return r?.secrets||{}}},S.internal&&(t.executeHubFunction=async(e,t,r)=>{if(n)return C.execute(e,t,g.default.sendBuffer,n,u.KemuHubServiceId,r);y("Service session id is not set. Cannot execute hub function.")});const U=t;return U._getRemoteInvoker=()=>C,U.getHubConfig=async()=>{if(!n)throw new Error("Service session id is not set. Cannot execute hub function.");const e=await C.execute(a.KemuHubFunctions.GetHubConfig,[],g.default.sendBuffer,n,u.KemuHubServiceId);return e?.[0]&&!e[0].kemuApiKey&&c&&(e[0].kemuApiKey=c),e?.[0]},U.getEdgeApiKey=async()=>{if(p)return void console.warn("This method [getEdgeApiKey] is NOT available in dev mode");if(!n)throw new Error("Service session id is not set. Cannot execute hub function.");const e=await C.execute(a.KemuHubFunctions.GetDecryptedEdgeApiKey,[],g.default.sendBuffer,n,u.KemuHubServiceId);return e?.[0]},t}}(s)),s));module.exports=de;
@@ -133,6 +133,8 @@ function requireKemuHub_t () {
133
133
  KemuHubFunctions["BroadcastEvent"] = "broadcastEvent";
134
134
  KemuHubFunctions["HubBroadcastEvent"] = "hubBroadcastEvent";
135
135
  KemuHubFunctions["ServiceManifest"] = "serviceManifest";
136
+ KemuHubFunctions["SendToRecipe"] = "sendToRecipe";
137
+ KemuHubFunctions["KemuComposerDisconnected"] = "kemu-composer-disconnected";
136
138
  KemuHubFunctions["GetState"] = "getState";
137
139
  KemuHubFunctions["SetState"] = "setState";
138
140
  KemuHubFunctions["SetOutputs"] = "setOutputs";
@@ -148,6 +150,13 @@ function requireKemuHub_t () {
148
150
  KemuHubFunctions["GetFileContentFromCacheId"] = "getFileContentFromCacheId";
149
151
  KemuHubFunctions["GetDecryptedEdgeApiKey"] = "getDecryptedEdgeApiKey";
150
152
  KemuHubFunctions["GetHubConfig"] = "getHubConfig";
153
+ KemuHubFunctions["GetRecipeDecryptedSecretsValues"] = "getRecipeDecryptedSecretsValues";
154
+ KemuHubFunctions["GetRecipeSecretMappings"] = "getRecipeSecretMappings";
155
+ KemuHubFunctions["AddRecipeSecretMapping"] = "addRecipeSecretMapping";
156
+ KemuHubFunctions["DeleteRecipeSecretMapping"] = "deleteRecipeSecretMapping";
157
+ KemuHubFunctions["GetHubSecrets"] = "getHubSecrets";
158
+ KemuHubFunctions["AddHubSecrets"] = "addHubSecrets";
159
+ KemuHubFunctions["DeleteHubSecret"] = "deleteHubSecret";
151
160
  })(KemuHubFunctions || (kemuHub_t.KemuHubFunctions = KemuHubFunctions = {}));
152
161
  var ServiceToServiceFunctions;
153
162
  (function (ServiceToServiceFunctions) {
@@ -173,6 +182,17 @@ function requireHelpers_t () {
173
182
  return helpers_t;
174
183
  }
175
184
 
185
+ var common_t = {};
186
+
187
+ var hasRequiredCommon_t;
188
+
189
+ function requireCommon_t () {
190
+ if (hasRequiredCommon_t) return common_t;
191
+ hasRequiredCommon_t = 1;
192
+ Object.defineProperty(common_t, "__esModule", { value: true });
193
+ return common_t;
194
+ }
195
+
176
196
  var hasRequiredCjs;
177
197
 
178
198
  function requireCjs () {
@@ -199,7 +219,8 @@ function requireCjs () {
199
219
  __exportStar(requireServiceWidget_t(), exports);
200
220
  __exportStar(requireServiceManifest_t(), exports);
201
221
  __exportStar(requireKemuHub_t(), exports);
202
- __exportStar(requireHelpers_t(), exports);
222
+ __exportStar(requireHelpers_t(), exports);
223
+ __exportStar(requireCommon_t(), exports);
203
224
  } (cjs));
204
225
  return cjs;
205
226
  }
package/mjs/service.d.ts CHANGED
@@ -182,16 +182,44 @@ export type TargetOutput = {
182
182
  /** id of the variant that defined the output */
183
183
  variantId?: string;
184
184
  };
185
- export type ValidEventContextValue = string | number | boolean | null | ValidEventContextValue[] | {
186
- [key: string]: ValidEventContextValue;
185
+ /**
186
+ * Information about a recipe.
187
+ */
188
+ export type RecipeContextInfo = {
189
+ /** a unique identifier set during recipe creation. It is meant to be unique and universal across all recipes */
190
+ uuid: string;
191
+ /** the id of the recipe in the database (if saved to the cloud) */
192
+ dbId?: string;
193
+ /** the id of the recipe in the pool */
194
+ poolId: string;
195
+ /** the name of the recipe */
196
+ name: string;
197
+ /** the type of recipe */
198
+ type: RecipeType;
199
+ /** the current version number of the recipe */
200
+ version: number;
201
+ /** the id of the author of the recipe */
202
+ authorId: string;
203
+ };
204
+ export type ValidEventContextValue = {
205
+ [key: string]: ValidEventContextValue | string | number | boolean | null;
187
206
  };
188
207
  export type WidgetType = string;
189
208
  export type SerializableWidgetInfo<T> = {
190
209
  /** the id of the current widget in the recipe */
191
210
  readonly widgetId: string;
192
211
  readonly type: WidgetType;
212
+ /**
213
+ * the id of the recipe in the pool
214
+ * @deprecated use `recipe.poolId` instead
215
+ **/
193
216
  readonly recipeId: string;
217
+ /**
218
+ * the name of the recipe
219
+ * @deprecated use `recipe.name` instead
220
+ */
194
221
  readonly recipeName: string;
222
+ readonly recipe: RecipeContextInfo;
195
223
  readonly variantId?: string;
196
224
  /** the state of the widget at the time the event was produced */
197
225
  readonly currentState: Readonly<T>;
@@ -269,18 +297,59 @@ export type ParentEventHandlerEvent<T extends WidgetState = WidgetState> = {
269
297
  /** information about the target (this) widget */
270
298
  target: PortEventInfo;
271
299
  targetVariantId?: string;
300
+ /**
301
+ * the id of the recipe in the pool
302
+ * @deprecated use `recipe.poolId` instead
303
+ */
272
304
  recipeId: string;
305
+ /**
306
+ * the name of the recipe
307
+ * @deprecated use `recipe.name` instead
308
+ */
273
309
  recipeName: string;
310
+ recipe: {
311
+ /**
312
+ * a unique identifier set during recipe creation. It is meant to be unique and universal across all recipes
313
+ */
314
+ uuid: string;
315
+ /**
316
+ * the id of the recipe in the database (if saved to the cloud)
317
+ */
318
+ dbId?: string;
319
+ /**
320
+ * the id of the recipe in the pool
321
+ */
322
+ poolId: string;
323
+ /**
324
+ * the name of the recipe
325
+ */
326
+ name: string;
327
+ /**
328
+ * the type of recipe
329
+ */
330
+ type: RecipeType;
331
+ /**
332
+ * the current version number of the recipe
333
+ */
334
+ version: number;
335
+ /**
336
+ * the id of the author of the recipe
337
+ */
338
+ authorId: string;
339
+ };
274
340
  /**
275
341
  * A context previously set by a parent widget of the same type.
276
342
  */
277
343
  eventContext?: ValidEventContextValue;
344
+ /** Execution path that led to the current invocation. */
345
+ currentPath: string[];
346
+ eventId: number | null;
278
347
  /** when data.value is binary (ImageData, etc) */
279
348
  /** the current state of the widget at the time of invocation */
280
349
  currentState: T;
281
350
  config?: RIExecuteConfig;
282
351
  };
283
- export type ServiceParentEvent<WS extends WidgetState = WidgetState> = Pick<ParentEventHandlerEvent<WS>, "data" | "source" | "target" | "eventContext">;
352
+ export type ServiceParentEvent<WS extends WidgetState = WidgetState> = Pick<ParentEventHandlerEvent<WS>, "data" | "source" | "target" | "eventContext" | "currentPath" | "eventId">;
284
353
  export type ServiceParentEventHandler<T extends WidgetState = WidgetState> = (event: ServiceParentEvent<T>, context: WidgetContext<T>) => Promise<void>;
285
354
  /**
286
355
  * Handles custom ui events. Any returned value will be passed back to the caller.
@@ -298,8 +367,12 @@ export type EnvironmentInfo<T extends WidgetState = WidgetState> = {
298
367
  widgetId: string;
299
368
  /** the id of the widget variant */
300
369
  variantId?: string;
301
- /** the id of the recipe in the pool. */
370
+ /**
371
+ * the id of the recipe in the pool
372
+ * @deprecated use `recipe.poolId` instead
373
+ */
302
374
  recipeId: string;
375
+ recipe: RecipeContextInfo;
303
376
  /** the current state of the widget */
304
377
  currentState: Readonly<T>;
305
378
  /**
@@ -315,14 +388,19 @@ export type EnvironmentInfo<T extends WidgetState = WidgetState> = {
315
388
  */
316
389
  export type GetDefaultStateHandler<T extends WidgetState = WidgetState> = () => T | Promise<T>;
317
390
  export type TerminateContext<T extends WidgetState = WidgetState> = {
391
+ /** @deprecated use `recipe.poolId` instead */
318
392
  recipeId: string;
393
+ recipe: RecipeContextInfo;
319
394
  widgetId: string;
320
395
  variantId?: string;
321
396
  currentState: Readonly<T>;
322
397
  };
323
398
  export type InitializeContext<T extends WidgetState = WidgetState> = {
399
+ /** @deprecated use `recipe.poolId` instead */
324
400
  recipeId: string;
401
+ /** @deprecated use `recipe.name` instead */
325
402
  recipeName: string;
403
+ recipe: RecipeContextInfo;
326
404
  widgetId: string;
327
405
  variantId?: string;
328
406
  currentState: Readonly<T>;
@@ -333,6 +411,13 @@ export type InitializeContext<T extends WidgetState = WidgetState> = {
333
411
  * This is only populated win web-mode when the service is initialized.
334
412
  */
335
413
  kemuApiKey?: string;
414
+ secrets: {
415
+ /**
416
+ * Tells Kemu-Composer the service needs access to a secret. Calling this method allows the secret to appear in the
417
+ * Secrets Mapping modal.
418
+ **/
419
+ requestAccess: (names: string[]) => void;
420
+ };
336
421
  };
337
422
  export type InitializeServiceHandler<T extends WidgetState = WidgetState> = (context: InitializeContext<T>) => Promise<T | null | void | undefined>;
338
423
  export type TerminateServiceHandler<T extends WidgetState = WidgetState> = (context: TerminateContext<T>) => Promise<void>;
@@ -352,6 +437,8 @@ export type ServiceBroadcastConfig = {
352
437
  * The id of the recipe the event is intended for.
353
438
  * If not provided, the event is broadcast to all recipes.
354
439
  */
440
+ targetRecipePoolId?: string;
441
+ /** @deprecated use `targetRecipePoolId` instead */
355
442
  targetRecipeId?: string;
356
443
  /**
357
444
  * The id of the widget the event is intended for.
@@ -364,6 +451,16 @@ export type ServiceBroadcastConfig = {
364
451
  * if the event data has fundamentally changed.
365
452
  */
366
453
  eventContext?: ValidEventContextValue;
454
+ /**
455
+ * The execution path that led to the current invocation.
456
+ */
457
+ currentPath: string[];
458
+ /**
459
+ * The id of the event to forward if this broadcast is the continuation of a previous invocation.
460
+ * Set it to 'null' to auto-generate an event. Default is 'null'
461
+ * If not provided, the event is broadcast to all recipes.
462
+ */
463
+ eventId?: number;
367
464
  };
368
465
  /**
369
466
  * Instance of a Kemu Widget library. Used by Widget services to integrate with the Kemu Hub.
@@ -385,6 +482,16 @@ export type KemuService<T extends Record<string, any> = Record<string, any>> = {
385
482
  * Use it to clean up resources of an instance before it is terminated.
386
483
  */
387
484
  onTerminate: (cb: TerminateServiceHandler<T>) => void;
485
+ /**
486
+ * Invoked when a Kemu Composer instance is disconnected.
487
+ */
488
+ onKemuComposerDisconnected: (cb: (config: {
489
+ /**
490
+ * Information about the recipe that was running in the Kemu Composer instance when it was disconnected.
491
+ * Use this to clean up resources of the service for this recipe.
492
+ **/
493
+ recipe: RecipeContextInfo;
494
+ }) => void) => void;
388
495
  /**
389
496
  * Invoked when a service instance is added to the workspace (in Kemu Compose)
390
497
  * or a recipe is loaded.
@@ -443,7 +550,13 @@ export type KemuService<T extends Record<string, any> = Record<string, any>> = {
443
550
  *
444
551
  * @param config the configuration of the broadcast event.
445
552
  */
446
- broadcastEvent: (config: ServiceBroadcastConfig) => Promise<void>;
553
+ broadcastEvent: (config: Omit<ServiceBroadcastConfig, "currentPath"> & {
554
+ currentPath?: string[];
555
+ }) => Promise<void>;
556
+ /**
557
+ * Sends data to a target recipe.
558
+ * @param config the configuration of the send to recipe event.
559
+ */
447
560
  /**
448
561
  * Registers the path to a file or folder the recipe depends on. When the recipe is exported,
449
562
  * the dependency will be included in the generated package.
@@ -473,6 +586,20 @@ export type KemuService<T extends Record<string, any> = Record<string, any>> = {
473
586
  * @param depPath the relative path of the dependency in the recipe.
474
587
  */
475
588
  resolveRuntimeDependencyPath: (depPath: string) => string;
589
+ /**
590
+ * Access to the secrets of the service.
591
+ */
592
+ secrets: {
593
+ /**
594
+ * Reads the value of a secret.
595
+ * @param name the name of the secret to read
596
+ * @returns a map of secret names to their values, or null if the secret as not been mapped to the recipe
597
+ **/
598
+ read: (config: {
599
+ names: string[];
600
+ recipeUuid: string;
601
+ }) => Promise<Record<string, string | null>>;
602
+ };
476
603
  };
477
604
  export declare const KemuHubServiceId = 0;
478
605
  /**
package/mjs/service.js CHANGED
@@ -1 +1 @@
1
- import{readFile as e}from"fs/promises";import t from"minimist";import n from"path";import r from"node-ipc";import a from"debug";var i,o,s,c,d,u,l,f;!function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}(i||(i={})),function(e){e[e.Number=0]="Number",e[e.String=1]="String",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Array=3]="Array",e[e.Boolean=4]="Boolean",e[e.JsonObj=5]="JsonObj",e[e.Anything=6]="Anything",e[e.ImageData=7]="ImageData",e[e.AudioBuffer=8]="AudioBuffer",e[e.Rect=9]="Rect",e[e.Point=10]="Point",e[e.ImageBitmap=11]="ImageBitmap",e[e.BinaryFile=12]="BinaryFile"}(o||(o={})),function(e){e.Number="Number",e.String="String",e.ArrayBuffer="ArrayBuffer",e.Array="Array",e.Boolean="Boolean",e.JsonObj="JsonObj",e.Anything="Anything",e.ImageData="ImageData",e.AudioBuffer="AudioBuffer",e.Rect="Rect",e.Point="Point",e.ImageBitmap="ImageBitmap",e.BinaryFile="BinaryFile"}(s||(s={})),function(e){e.Javascript="js",e.Python="py",e.Executable="exe"}(c||(c={})),function(e){e.IpcAcknowledge="iack:",e.SocketAcknowledge="sack:",e.AcknowledgeResponse="ackr:",e.ServicesListChanged="update-services",e.SendManifest="send-manifest",e.BroadcastStart="broadcast-start",e.BroadcastEnd="broadcast-end",e.AssumeSession="assume:"}(d||(d={})),function(e){e.GetServices="getServices",e.SubscribeToService="subscribeToService",e.UnsubscribeFromService="unsubscribeFromService",e.GetServiceContents="getServiceContents",e.SocketAckResponse="socketAckResponse",e.ShowSecretsConfigScreen="showSecretsConfigScreen",e.GetMappedSecrets="getMappedSecrets",e.GetSecretContexts="getSecretContexts",e.OnParentEvent="onParentEvent",e.GetDefaultState="getDefaultState",e.BroadcastEvent="broadcastEvent",e.HubBroadcastEvent="hubBroadcastEvent",e.ServiceManifest="serviceManifest",e.GetState="getState",e.SetState="setState",e.SetOutputs="setOutputs",e.UIEvent="uiEvent",e.GetSystemInfo="getSystemInfo",e.InitializeInstance="initializeInstance",e.TerminateInstance="terminateInstance",e.UninstallService="uninstallService",e.ChooseDirectoryDialog="chooseDirectoryDialog",e.ChooseFileDialog="chooseFileDialog",e.GetUniqueId="getUniqueId",e.RebootToInstallUpdate="rebootToInstallUpdate",e.GetFileContentFromCacheId="getFileContentFromCacheId",e.GetDecryptedEdgeApiKey="getDecryptedEdgeApiKey",e.GetHubConfig="getHubConfig"}(u||(u={})),function(e){e.SetDependencyPath="setDependencyPath",e.GetDependencyPath="getDependencyPath"}(l||(l={})),function(e){e.IPC="ipc",e.WS="ws"}(f||(f={}));const g=0,y=e=>{try{return JSON.parse(e)}catch(e){return null}},p="undefined"!=typeof window,m=(e,t,n,r="srgb")=>{let a;return a=e instanceof Uint8ClampedArray?e:new Uint8ClampedArray(e),{data:a,width:t,height:n,colorSpace:r,_kemuType:o.ImageData}};var h={id:"widgets",retry:1500,silent:!0,rawBuffer:!0,appspace:"kemu.",encoding:"hex"};const I={protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8},v={protocolPrefix:4,txtLength:4},S=Object.values(I).reduce(((e,t)=>e+t),0),b=Object.values(v).reduce(((e,t)=>e+t),0),w=["width","height","colorSpace"],A=(e,t)=>{const n={},r=[];let a=0,i=Array.isArray(e)?[]:{};const o=(e,i)=>{const s=(e=>{const t="undefined"!=typeof Buffer&&e instanceof Buffer,n=e instanceof ArrayBuffer,r=e instanceof Uint8ClampedArray,a=e instanceof Uint8Array,i=e instanceof Int8Array;return t?"Buffer":n?"ArrayBuffer":r?"Uint8ClampedArray":a?"Uint8Array":i?"Int8Array":null})(e);if(!s){if(Array.isArray(e)){const t=[];for(let n=0;n<e.length;n++)t[n]=o(e[n],`${i}[${n}]`);return t}if("object"==typeof e){const t={},n=(e=>{const t=e instanceof Int16Array,n=e instanceof Uint16Array,r=e instanceof Int32Array,a=e instanceof Uint32Array,i=e instanceof Float32Array,o=e instanceof Float64Array,s=e instanceof BigInt64Array,c=e instanceof BigUint64Array;return t?"Int16Array":n?"Uint16Array":r?"Int32Array":a?"Uint32Array":i?"Float32Array":o?"Float64Array":s?"BigInt64Array":c?"BigUint64Array":null})(e);if(n)throw new Error(`Unsupported binary type [${n}] at path "${i}"`);for(const n in e)Object.hasOwn(e,n)||w.includes(n)||console.warn(`Allowing inherited property: ${n} from path: ${i}`),t[n]=o(e[n],`${i.length?`${i}.`:""}${n}`);return t}return e}n[i]={index:a,length:e.byteLength,binaryType:s},"Buffer"===t?r.push(Buffer.from(e)):"ArrayBuffer"===s?r.push(e):r.push(e.buffer),a+=e.byteLength};i=o(e,"");let s=null;if(r.length>1)if("ArrayBuffer"===t){const e=r.reduce(((e,t)=>e+t.byteLength),0),t=new Uint8Array(e);let n=0;for(let e=0;e<r.length;e++)t.set(new Uint8Array(r[e]),n),n+=r[e].byteLength;s=t.buffer}else{s=Buffer.concat(r)}else 1===r.length&&(s=r[0]);return s?{map:n,combinedData:s,sourceCopy:i}:null},B=(e,t,n,r)=>{const a=t.match(/(\[\d+\])|([^[\].]+)/g)||[];let i=e;for(let e=0;e<a.length;e++){let t=a[e];const r=t.startsWith("[")&&t.endsWith("]"),o=e===a.length-1;if(r){t=t.slice(1,-1);const r=parseInt(t,10);if(!Array.isArray(i))throw new Error(`Expected an array at key "${a.slice(0,e).join(".")}" but found an object.`);o?i[r]=n:(i[r]||(i[r]=a[e+1].startsWith("[")?[]:{}),i=i[r])}else o?i[t]=n:(i[t]||(i[t]=a[e+1].startsWith("[")?[]:{}),i=i[t])}return e},L=(e,t,n)=>{const r="undefined"!=typeof Buffer,a=t instanceof Uint8Array;for(const i in n)if(Object.hasOwn(n,i)){const{index:o,length:s,binaryType:c}=n[i];let d=null;if(r&&t instanceof Buffer)switch(c){case"Buffer":d=t.subarray(o,o+s);break;case"ArrayBuffer":d=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s);break;case"Uint8Array":d=new Uint8Array(t.subarray(o,o+s));break;case"Uint8ClampedArray":d=new Uint8ClampedArray(t.subarray(o,o+s));break;case"Int8Array":d=new Int8Array(t.subarray(o,o+s))}else if(t instanceof ArrayBuffer||t instanceof Uint8Array)switch(c){case"Buffer":if(r){d=Buffer.from(t.slice(o,o+s));break}case"ArrayBuffer":d=a?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s):t.slice(o,o+s);break;case"Uint8Array":d=a?t.slice(o,o+s):new Uint8Array(t.slice(o,o+s));break;case"Uint8ClampedArray":d=new Uint8ClampedArray(t.slice(o,o+s));break;case"Int8Array":d=new Int8Array(t.slice(o,o+s))}d&&B(e,i,d)}return e},U=e=>a(e),E="KMSG",C="KCMD",D=U("klProtocol");var k={encode:(e,t,n)=>{const r={json:e.json},a=A(r.json,"Buffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=Buffer.from(s),d=c.byteLength,u=I.protocolPrefix+I.protocolVersion+I.jsonLength+I.binaryLength+I.fromServiceId+I.toServiceId+I.sentAt+d+o,l=Buffer.alloc(u),f=Date.now();let g=0;return l.write(E,g),g+=I.protocolPrefix,l.writeUInt8(1,g),g+=I.protocolVersion,l.writeUInt32LE(d,g),g+=I.jsonLength,l.writeUInt32LE(o,g),g+=I.binaryLength,l.writeUInt32LE(t,g),g+=I.fromServiceId,l.writeUInt32LE(n,g),g+=I.toServiceId,l.writeBigInt64LE(BigInt(f),g),g+=I.sentAt,c.copy(l,g),g+=d,i&&o&&i.copy(l,g),l},decodeHeader:e=>{let t=0;const n=e.toString("utf-8",t,I.protocolPrefix);if(t+=I.protocolPrefix,n!==E)return null;if(e.byteLength<S)return D(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const r=e.readUInt8(t);t+=I.protocolVersion;const a=e.readUInt32LE(t);t+=I.jsonLength;const i=e.readUInt32LE(t);t+=I.binaryLength;const o=e.readUInt32LE(t);t+=I.fromServiceId;const s=e.readUInt32LE(t);t+=I.toServiceId;const c=e.readBigInt64LE(t);t+=I.sentAt;const d=a+i,u=e.subarray(t,t+d),l=e.subarray(0,S);let f=null;return e.byteLength-S-a-i>0&&(f=e.subarray(S+a+i)),{header:{protocolVersion:r,jsonLength:a,binaryLength:i,fromServiceId:o,toServiceId:s,sentAt:new Date(Number(c)),packages:[u],headerPackage:l},remaining:f}},decodeFullKlMessage:e=>{const t=Buffer.concat(e.packages),n=t.subarray(0,e.jsonLength).toString(),r=t.subarray(e.jsonLength,e.jsonLength+e.binaryLength),a=y(n);if(!a?.json)return D("Invalid JSON in KL message"),null;a.jsonBinaryMap&&r.byteLength&&L(a.json,r,a.jsonBinaryMap);const i=Buffer.concat([e.headerPackage,t]);let o=i,s=null;const c=S+e.jsonLength+e.binaryLength;return i.byteLength>c&&(s=i.subarray(c),o=i.subarray(0,c)),{message:{json:a.json,rawMessage:o},remaining:s}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<S)return D("Invalid Header Size"),e;let n=0;return n+=I.protocolPrefix,n+=I.protocolVersion,n+=I.jsonLength,n+=I.binaryLength,void 0!==t.fromServiceId&&e.writeUInt32LE(t.fromServiceId,n),n+=I.fromServiceId,void 0!==t.toServiceId&&e.writeUInt32LE(t.toServiceId,n),e},encodeCommand:e=>{let t=0;const n=Buffer.from(e),r=n.byteLength,a=b+r,i=Buffer.alloc(a);return i.write(C,t),t+=v.protocolPrefix,i.writeUint32LE(r,t),t+=v.txtLength,n.copy(i,t),i},decodeCommand:e=>{let t=0;if(e.byteLength<b)return{command:null};const n=e.toString("utf-8",t,v.protocolPrefix);if(t+=v.protocolPrefix,n!==C)return{command:null};const r=e.readUInt32LE(t);t+=v.txtLength;const a=e.toString("utf-8",t,t+r),i=e.byteLength-b-r;let o=null;i>0&&(o=e.subarray(b+r));let s=0;return i<0&&(s=Math.abs(i)),{command:a,remainingData:o,missing:s}}};const j="KMSG",x="KCMD",P=U("klProtocol"),$=new TextEncoder;var R={encode:(e,t,n)=>{const r={json:e.json},a=A(e.json,"ArrayBuffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=$.encode(s),d=c.byteLength,u=new ArrayBuffer(I.protocolPrefix+I.protocolVersion+I.jsonLength+I.binaryLength+I.fromServiceId+I.toServiceId+I.sentAt+d+o),l=new DataView(u),f=new Uint8Array(u),g=Date.now();let y=0;for(let e=0;e<4;++e)f[y++]=j.charCodeAt(e);return l.setUint8(y,1),y+=I.protocolVersion,l.setUint32(y,d,!0),y+=I.jsonLength,l.setUint32(y,o,!0),y+=I.binaryLength,l.setUint32(y,t,!0),y+=I.fromServiceId,l.setUint32(y,n,!0),y+=I.toServiceId,l.setBigInt64(y,BigInt(g),!0),y+=I.sentAt,f.set(c,y),y+=d,i&&o&&f.set(new Uint8Array(i),y),u},decodeHeader:e=>{const t=new DataView(e);let n=0,r="";for(let e=0;e<I.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==j)return null;if(e.byteLength<S)return P.log(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const a=t.getUint8(n);n+=I.protocolVersion;const i=t.getUint32(n,!0);n+=I.jsonLength;const o=t.getUint32(n,!0);n+=I.binaryLength;const s=t.getUint32(n,!0);n+=I.fromServiceId;const c=t.getUint32(n,!0);n+=I.toServiceId;const d=t.getBigInt64(n,!0);n+=I.sentAt;const u=i+o,l=e.slice(n,n+u),f=new Uint8Array(e,0,S);let g=null;if(e.byteLength-S-i-o>0){g=new Uint8Array(e,S+i+o).slice().buffer}return{header:{protocolVersion:a,jsonLength:i,binaryLength:o,fromServiceId:s,toServiceId:c,sentAt:new Date(Number(d)),packages:[l],headerPackage:f.slice().buffer},remaining:g}},decodeFullKlMessage:e=>{const t=e.packages.reduce(((e,t)=>e+t.byteLength),0),n=new Uint8Array(t);let r,a=0;for(const t of e.packages)r=new Uint8Array(t),n.set(r,a),a+=r.byteLength;const i=(new TextDecoder).decode(n.subarray(0,e.jsonLength)),o=n.subarray(e.jsonLength,e.jsonLength+e.binaryLength),s=y(i);if(!s?.json)return P.log("Invalid JSON in KL message"),null;s.jsonBinaryMap&&o.byteLength&&L(s.json,o,s.jsonBinaryMap);const c=new Uint8Array(e.headerPackage.byteLength+n.byteLength);c.set(new Uint8Array(e.headerPackage),0),c.set(n,e.headerPackage.byteLength);let d=c,u=null;const l=S+e.jsonLength+e.binaryLength;return c.byteLength>l&&(u=c.subarray(l),d=c.subarray(0,l)),{message:{json:s.json,...o.length?{binaryData:o.buffer}:{},rawMessage:d.buffer},remaining:u?.buffer??null}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<S)return P("Invalid Header Size"),e;let n=0;n+=I.protocolPrefix,n+=I.protocolVersion,n+=I.jsonLength,n+=I.binaryLength;const r=new DataView(e);return void 0!==t.fromServiceId&&r.setUint32(n,t.fromServiceId,!0),n+=I.fromServiceId,void 0!==t.toServiceId&&r.setUint32(n,t.toServiceId,!0),e},encodeCommand:e=>{let t=0;const n=$.encode(e),r=n.byteLength,a=new ArrayBuffer(b+r),i=new DataView(a),o=new Uint8Array(a);for(let e=0;e<4;++e)o[t++]=x.charCodeAt(e);return i.setUint32(t,r,!0),t+=v.txtLength,o.set(n,t),a},decodeCommand:e=>{const t=new DataView(e);let n=0;if(e.byteLength<b)return{command:null};let r="";for(let e=0;e<v.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==x)return{command:null};const a=t.getUint32(n,!0);n+=v.txtLength;const i=e.byteLength-b-a,o=new Uint8Array(e,n,Math.min(a,e.byteLength-b)),s=(new TextDecoder).decode(o);let c=null;i>0&&(c=e.slice(b+a));let d=0;return i<0&&(d=Math.abs(i)),{command:s,remainingData:c,missing:d}}};const N=U("klTransmissionManager");let M=k;p&&(M=R);var O=M;let F,T,H,K,G=null;const _=(()=>{const e=(t,n,r,a)=>{let i=n,o=null;const s=t instanceof ArrayBuffer;if(N(`RAW: ${t.toString()}`),!i||i.partialHeaderData){let c;if(s?(c=i?.partialHeaderData?new Uint8Array([...new Uint8Array(i.partialHeaderData),...new Uint8Array(t)]).buffer:t,o=R.decodeHeader(c)):(c=i?.partialHeaderData?Buffer.concat([i.partialHeaderData,t]):t,o=k.decodeHeader(c)),!o){const{command:t,missing:i,remainingData:o}=s?R.decodeCommand(c):k.decodeCommand(c);return t?a({command:t,complete:!0,rawMessage:c}):N(i?`ERROR: Missing ${i} bytes to complete the command. This partial command will be aborted.`:`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`),o?(N(`${o.byteLength} bytes remain after processing command. Re-analyzing...`),e(o,n,r,a)):void 0}if(o.partialHeader)return i={firstPackageAt:Date.now(),partialHeaderData:c},r(i);if(!o.header)return N(`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`);const d=o.header;i={firstPackageAt:Date.now(),header:{...d,totalBytesReceived:d.packages[0].byteLength,totalBytesExpected:d.binaryLength+d.jsonLength,remaining:o.remaining}},r(i)}else i.header&&i.header.totalBytesReceived<i.header.totalBytesExpected&&(i.header.packages.push(t),i.header.totalBytesReceived+=t.byteLength,r(i));if(i.header&&i.header.totalBytesReceived>=i.header.totalBytesExpected){const t=Date.now()-i.header.sentAt.getTime(),n=Date.now()-i.firstPackageAt;N(`Received ${i.header.totalBytesReceived} of ${i.header.totalBytesExpected} expected in ${t} ms, elapsed since first package: ${n}ms`);const o=s?R.decodeFullKlMessage(i.header):k.decodeFullKlMessage(i.header),c=i.header.totalBytesReceived,d=i.header.remaining;r(null),o&&a({klMessage:o.message,complete:!0,sourceServiceId:i.header.fromServiceId,targetServiceId:i.header.toServiceId,rawMessage:o.message.rawMessage});let u=d;if(o?.remaining&&(u=s?d?((e,t)=>{const n=e.byteLength+t.byteLength,r=new ArrayBuffer(n),a=new Uint8Array(e),i=new Uint8Array(t),o=new Uint8Array(r);return o.set(a),o.set(i,a.length),r})(d,o.remaining):o.remaining:d?Buffer.concat([d,o.remaining]):o.remaining),u)return N(`${u.byteLength} bytes remaining after processing message with ${c} bytes of data. Re-analyzing...`),e(u,null,r,a)}};return e})(),V=U("ipcClient"),W=e=>{const t=h.id;r.of[t].emit(e)};var J,z={connect:e=>{h.id=e?.id||h.id,h.appspace=e?.appSpace||h.appspace,r.config={...r.config,...h};const t=h.id;r.connectTo(t,(()=>{r.of[t].on("connect",(()=>{V("Connected to server"),G=null,T&&T()})),r.of[t].on("data",(e=>{_(e,G,(e=>G=e),(e=>{if(e.complete)return e.command?(V(`Received command: ${e.command}`),void(F&&F(e.command))):void(e.klMessage&&H&&H({send:W,transmission:{sourceServiceId:e.sourceServiceId??-1,targetServiceId:e.targetServiceId??-1,rawMessage:e.rawMessage},json:e.klMessage.json}))}))})),r.of[t].on("disconnect",(()=>{V(`Disconnected from ${t}`),G=null,K&&K()}))}))},sendCommand:e=>{const t=h.id,n=O.encodeCommand(e);r.of[t].emit(n)},sendBuffer:W,onCommand:e=>F=e,onMessageReceived:e=>H=e,onClientConnected:e=>T=e,onClientDisconnected:e=>K=e};!function(e){e.FunctionNotFound="FNC_NOT_FOUND",e.ParentEventCallbackError="PARENT_EVENT_CALLBACK_ERROR"}(J||(J={}));const q=3e4;let Q=Math.ceil(Date.now()/1e3);function X(e){const t={};let n=console.log;const r={};let a=e||String(Date.now());const i={},o=e=>!i[e],s=(e,t,n,r,a,i)=>{let s=p?new ArrayBuffer(0):Buffer.alloc(0);const c={json:{functionName:e,args:i.success?i.success:[i],messageId:t,type:i.success?"response":"error"}};return o(r)&&(s=O.encode(c,n,r)),a(s,{msg:c,sourceServiceId:n,targetServiceId:r})};return{setLogger:e=>{n=e},processMessage:(e,a,i,o)=>{if(!o)return!1;const c=o;if(t[c.messageId]){const e=t[c.messageId];return e&&(clearTimeout(e.timer),e.fulfilled||(e.fulfilled=!0,"response"===c.type?e.resolve(c.args):"error"===c.type&&e.reject(c.args[0])),delete t[c.messageId]),!0}if("execute"!==c.type&&n&&n(`No pending execution found for message id "${c.messageId}"`),"execute"===c.type){const t=r[c.functionName];if(t){const n=e=>{s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,e)};t({transport:e,args:c.args,reply:n,messageId:c.messageId,sourceServiceId:i.sourceServiceId,send:a})}else{const e=`Function "${c.functionName}" not found.`;n&&n(e),s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,{error:e,errCode:"FNC_NOT_FOUND"})}return!0}return!1},execute:async(e,r,i,s,c,d)=>{if(!i){const e="No send buffer function provided.";throw n&&n(e),e}Q+=1;const u=`${a}-${Q}-exec-${e.substring(0,10)}`,l={messageId:u,functionName:e,send:i,sourceServiceId:s,targetServiceId:c,args:r||[],fulfilled:!1,resolve:()=>{},reject:()=>{}};l.promise=new Promise(((e,t)=>{l.resolve=e,l.reject=t}));let f=p?new ArrayBuffer(0):Buffer.alloc(0);const g={json:{functionName:e,args:r,messageId:u,type:"execute"}};o(c)&&(f=O.encode(g,s,c)),t[u]=l,n&&n(`Calling remote function "${e}" with message id "${u}"`);const y="true"===process.env.NO_INVOKE_TIMEOUT;return d?.async?(l.fulfilled=!0,l.resolve([void 0]),delete t[u]):0===d?.timeout||y||(l.timer=setTimeout((()=>{n&&n(`Remote function ${u} timed out`);const r=t[u];r&&!r.fulfilled&&(r.fulfilled=!0,l.reject(`Function ${e} Timed out`)),delete t[u]}),d?.timeout||q)),i(f,{sourceServiceId:s,targetServiceId:c,msg:g}),l.promise},sendResponse:s,registerFunction:(e,t)=>{r[e]=t},getTransportSendFunction:e=>{const n=t[e];return n?n.send:null},setServiceName:e=>{a=e},getPendingExecutions:()=>t,rejectAllPending:e=>{Object.keys(t).forEach((n=>{const r=t[n];r&&!r.fulfilled&&(clearTimeout(r.timer),r.fulfilled=!0,r.reject(e),delete t[n])}))},broadcast:(e,t,r,i)=>{Q+=1;const s=`${a}-${Q}-multicast-${e.substring(0,10)}`;let c=p?new ArrayBuffer(0):Buffer.alloc(0);const d={json:{functionName:e,args:t,messageId:s,type:"execute"}};let u=o(r[0].serviceId);u&&(c=O.encode(d,i,r[0].serviceId));for(let t=0;t<r.length;t++)try{const a=r[t];n&&n(`Broadcasting function "${e}" with message id "${s}" to client [${a.serviceId}]`),0!==t&&(u=o(a.serviceId),u&&(c=O.patchEncodedHeader(c,{toServiceId:a.serviceId}))),a.sendFn(c,{msg:d,sourceServiceId:i,targetServiceId:a.serviceId})}catch(e){n&&n(`Error broadcasting to client at index ${t}`)}},disableServiceEncoding:(e,t)=>{i[e]=t}}}const Y=U("kemuWidgetService"),Z=t(process.argv.slice(2));function ee(t){const r={},a=process.env.KEMU_WIDGET_SESSION_ID;let i,o,s,c,g=!1;const p={};let m,h,I,v,S,b,w,A=null;const B=new X;B.setLogger(Y);r.start=async(r,c)=>{const d=r||n.resolve(n.dirname(process.argv[1]),"manifest.json");s=n.dirname(d);const l=await e(d,"utf-8"),p=y(l);if(!p)throw new Error("Error parsing manifest file.");let m;if(p.inputs||(p.inputs=[]),p.outputs||(p.outputs=[]),p.widgetUI)try{m=await e(n.join(s,"widgetUI.js"))}catch(e){Y(`Error loading widgetUI file ${p.name}: ${e}`)}if(p.svgIcon)try{const t=await e(n.join(s,p.svgIcon),"utf-8");p.svgIcon=t}catch(e){Y(`Error loading icon for service ${p.name}: ${e}`)}o=((e,t,n)=>({...e,path:t,...e.widgetUI&&n?.widgetUIContents?{widgetUIContents:n.widgetUIContents}:{}}))(p,s,{widgetUIContents:m}),g=o.name.startsWith("test."),o.path=s,o.internal=Z.internal||!1,g?Y("Starting Kemu Service in Dev mode"):((e=>{const t=e||Z.sessionId||a;if(!t)throw new Error("Missing sessionId. Expected service to be launched with a sessionId as first argument, or the KEMU_WIDGET_SESSION_ID environment variable to be set.");i=parseInt(String(t))})(c),Y(`Starting Kemu Service with session id: ${i}`)),B.setServiceName(`${o.name}_${o.version}`),z.onCommand(L),z.onMessageReceived((({json:e,transmission:t})=>B.processMessage(f.IPC,z.sendBuffer,t,e))),B.registerFunction(u.OnParentEvent,E),B.registerFunction(u.GetDefaultState,U),B.registerFunction(u.UIEvent,k),B.registerFunction(u.InitializeInstance,C),B.registerFunction(u.TerminateInstance,D),z.onClientConnected((()=>{w&&w()})),z.onClientDisconnected((()=>{g&&(i=void 0)})),z.connect({appSpace:Z.ipcSpace||t?.ipc?.appSpace,id:Z.ipcId||t?.ipc?.id})};const L=e=>{((e,t)=>{const n=d.SocketAcknowledge,r=d.IpcAcknowledge,a=e.startsWith(n),i=e.startsWith(r);if(a||i){const i=e.split(a?n:r),o=parseInt(i[1]);return t&&t(o),o}})(e,(e=>{z.sendCommand(((e,t)=>`${d.AcknowledgeResponse}${e}:${t||""}`)(e,i||void 0)),!i&&g&&(Y("Dev mode detected, assuming service session id from ack request:",e),i=e)})),((e,t)=>{e===d.BroadcastStart&&t()})(e,(()=>{I&&I()})),((e,t)=>{e===d.BroadcastEnd&&t()})(e,(()=>{v&&v()})),((e,t)=>{e===d.SendManifest&&t()})(e,(()=>{Y("Sending manifest to hub"),i?B.execute(u.ServiceManifest,[{...o,devMode:g}],z.sendBuffer,i,0,{async:!0}):Y("Service session id is not set. Cannot send manifest.")})),((e,t)=>{if(e.startsWith(d.AssumeSession)){const n=e.split(d.AssumeSession);return t(parseInt(n[1])),!0}})(e,(e=>{i=e,Y(`Assumed session id ${e}`)}))},U=async e=>{if(h){const t=await h();return e.reply({success:[t]})}return e.reply({success:[{}]})},E=async e=>{if(!m)return Y("No onParentEvent callback defined. Skipping parent event."),e.reply({success:[]});const t=e.args[0],{source:n,target:r,data:a,recipeId:o,recipeName:s,currentState:c,targetVariantId:d,eventContext:l}=t;if(!i)return void Y("Service session id is not set. Cannot process parent event.");if(!n||!r||!a)return e.reply({error:"Invalid arguments, expected [source, target, data, context]"});const f=z.sendBuffer,g=async t=>B.execute(u.SetOutputs,[t],f,i,e.sourceServiceId,{timeout:0}),y={currentState:c,type:r.widgetType,widgetId:r.widgetId,variantId:d,recipeId:o,recipeName:s,setState:async t=>{const n={widgetId:r.widgetId,variantId:d,recipeId:o,newState:t};return B.execute(u.SetState,[n],f,i,e.sourceServiceId)},setOutputs:async(e,t)=>{const n={widgetId:r.widgetId,recipeId:o,outputs:e,finalState:t};await g(n)},setOutputsWithContext:async e=>{const t={...e,widgetId:r.widgetId,recipeId:o};await g(t)}};Y(`Invoking user-defined onParentEvent callback for event id "${e.messageId}"`),await m({data:a,source:n,target:r,eventContext:l},y).then((()=>{Y(`Replying SUCCESS to event id "${e.messageId}"`),e.reply({success:[]})})).catch((t=>{const n="string"==typeof t?t:t.message||t;Y(`Error invoking onParentEvent callback: ${n}`),e.reply({error:n,errCode:"PARENT_EVENT_CALLBACK_ERROR"})}))},C=async e=>{const[{currentState:t,recipeId:n,recipeName:r,widgetId:a,variantId:i,recipeType:o,currentDependencies:s,kemuApiKey:d}]=e.args;if(d&&(c=d),p[a]={currentRecipeId:n,variantId:i,currentSourceServiceId:e.sourceServiceId},S){const c={currentState:t,recipeId:n,recipeName:r,widgetId:a,variantId:i,recipeType:o,currentDependencies:s||{},kemuApiKey:d},u=await S(c);e.reply({success:[u]})}else e.reply({error:"Not implemented",errCode:"FNC_NOT_FOUND"})},D=async e=>{if(b){const[{currentState:t,recipeId:n,widgetId:r,variantId:a}]=e.args,i={currentState:t,recipeId:n,widgetId:r,variantId:a};await b(i),delete p[r]}e.reply({success:[]})},k=async e=>{if(A)try{const t=await A.apply(void 0,e.args);return e.reply({success:[t]})}catch(t){const n="string"==typeof t?t:JSON.stringify(t);return Y(`Error invoking UI Event handler: ${n}`),e.reply({error:n})}e.reply({error:"UI Events are not supported in this service."})},j=async e=>{if(!o.eventEmitter)throw new Error("This service does not support broadcasting events. Please set `eventEmitter` to true in your manifest file.");if(i)return B.execute(u.BroadcastEvent,e,z.sendBuffer,i,0,{async:!0});Y("Service session id is not set. Cannot broadcast event.")};r.broadcast=async(e,t)=>{const n=[{outputs:e,variantId:t}];await j(n)},r.broadcastEvent=async e=>{const t=[{outputs:e.outputs,variantId:e.variantId,eventContext:e.eventContext,targetRecipeId:e.targetRecipeId,targetWidgetId:e.targetWidgetId}];await j(t)},r.addDependencyPath=async(e,t,n)=>{if(!i)throw new Error("Not yet registered with the Hub");const r=p[n];if(!r.currentSourceServiceId||!r.currentRecipeId)throw new Error("Cannot invoke this method before initialization");const a={key:e,path:t,recipeId:r.currentRecipeId,widgetId:n};Y(`Adding dependency path for key "${e}" with path "${t}"`),await B.execute(l.SetDependencyPath,[a],z.sendBuffer,i,r.currentSourceServiceId)},r.getDependencyPath=async(e,t)=>{if(!i)throw new Error("Not yet registered with the Hub");const n=p[t];if(!n.currentSourceServiceId||!n.currentRecipeId)throw new Error("Cannot invoke this method before initialization");Y("Getting dependency path for key:",e);const r={key:e,recipeId:n.currentRecipeId,widgetId:t},[a]=await B.execute(l.GetDependencyPath,[r],z.sendBuffer,i,n.currentSourceServiceId);return Y("Dependency path response:",a),a},r.getUniqueId=async()=>{if(!i)throw new Error("Not yet registered with the Hub");const[e]=await B.execute(u.GetUniqueId,[],z.sendBuffer,i,0);return e},r.resolveRuntimeDependencyPath=e=>{if(!Z.recipePath)throw new Error("Cannot resolve runtime dependency without a recipe path. Missing [--recipePath] argument.");return n.resolve(Z.recipePath,e)},r.onGetDefaultState=e=>{h=e},r.onParentEvent=e=>{m=e},r.onTerminate=e=>{b=e},r.onInitialize=e=>{S=e},r.onConnected=e=>{w=e},r.onStartBroadcast=e=>{I=e},r.onStopBroadcast=e=>{v=e},r.onUIEvent=e=>{A=e},Z.internal&&(r.executeHubFunction=async(e,t,n)=>{if(i)return B.execute(e,t,z.sendBuffer,i,0,n);Y("Service session id is not set. Cannot execute hub function.")});const x=r;return x._getRemoteInvoker=()=>B,x.getHubConfig=async()=>{if(!i)throw new Error("Service session id is not set. Cannot execute hub function.");const e=await B.execute(u.GetHubConfig,[],z.sendBuffer,i,0);return e?.[0]&&!e[0].kemuApiKey&&c&&(e[0].kemuApiKey=c),e?.[0]},x.getEdgeApiKey=async()=>{if(g)return void console.warn("This method [getEdgeApiKey] is NOT available in dev mode");if(!i)throw new Error("Service session id is not set. Cannot execute hub function.");const e=await B.execute(u.GetDecryptedEdgeApiKey,[],z.sendBuffer,i,0);return e?.[0]},r}export{o as DataType,g as KemuHubServiceId,m as createImageDataLike,ee as default};
1
+ import{readFile as e}from"fs/promises";import t from"minimist";import n from"path";import r from"node-ipc";import a from"debug";var i,o,s,c,d,u,l,g;!function(e){e.Browser="browser",e.Cloud="cloud",e.Desktop="desktop"}(i||(i={})),function(e){e[e.Number=0]="Number",e[e.String=1]="String",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Array=3]="Array",e[e.Boolean=4]="Boolean",e[e.JsonObj=5]="JsonObj",e[e.Anything=6]="Anything",e[e.ImageData=7]="ImageData",e[e.AudioBuffer=8]="AudioBuffer",e[e.Rect=9]="Rect",e[e.Point=10]="Point",e[e.ImageBitmap=11]="ImageBitmap",e[e.BinaryFile=12]="BinaryFile"}(o||(o={})),function(e){e.Number="Number",e.String="String",e.ArrayBuffer="ArrayBuffer",e.Array="Array",e.Boolean="Boolean",e.JsonObj="JsonObj",e.Anything="Anything",e.ImageData="ImageData",e.AudioBuffer="AudioBuffer",e.Rect="Rect",e.Point="Point",e.ImageBitmap="ImageBitmap",e.BinaryFile="BinaryFile"}(s||(s={})),function(e){e.Javascript="js",e.Python="py",e.Executable="exe"}(c||(c={})),function(e){e.IpcAcknowledge="iack:",e.SocketAcknowledge="sack:",e.AcknowledgeResponse="ackr:",e.ServicesListChanged="update-services",e.SendManifest="send-manifest",e.BroadcastStart="broadcast-start",e.BroadcastEnd="broadcast-end",e.AssumeSession="assume:"}(d||(d={})),function(e){e.GetServices="getServices",e.SubscribeToService="subscribeToService",e.UnsubscribeFromService="unsubscribeFromService",e.GetServiceContents="getServiceContents",e.SocketAckResponse="socketAckResponse",e.ShowSecretsConfigScreen="showSecretsConfigScreen",e.GetMappedSecrets="getMappedSecrets",e.GetSecretContexts="getSecretContexts",e.OnParentEvent="onParentEvent",e.GetDefaultState="getDefaultState",e.BroadcastEvent="broadcastEvent",e.HubBroadcastEvent="hubBroadcastEvent",e.ServiceManifest="serviceManifest",e.SendToRecipe="sendToRecipe",e.KemuComposerDisconnected="kemu-composer-disconnected",e.GetState="getState",e.SetState="setState",e.SetOutputs="setOutputs",e.UIEvent="uiEvent",e.GetSystemInfo="getSystemInfo",e.InitializeInstance="initializeInstance",e.TerminateInstance="terminateInstance",e.UninstallService="uninstallService",e.ChooseDirectoryDialog="chooseDirectoryDialog",e.ChooseFileDialog="chooseFileDialog",e.GetUniqueId="getUniqueId",e.RebootToInstallUpdate="rebootToInstallUpdate",e.GetFileContentFromCacheId="getFileContentFromCacheId",e.GetDecryptedEdgeApiKey="getDecryptedEdgeApiKey",e.GetHubConfig="getHubConfig",e.GetRecipeDecryptedSecretsValues="getRecipeDecryptedSecretsValues",e.GetRecipeSecretMappings="getRecipeSecretMappings",e.AddRecipeSecretMapping="addRecipeSecretMapping",e.DeleteRecipeSecretMapping="deleteRecipeSecretMapping",e.GetHubSecrets="getHubSecrets",e.AddHubSecrets="addHubSecrets",e.DeleteHubSecret="deleteHubSecret"}(u||(u={})),function(e){e.SetDependencyPath="setDependencyPath",e.GetDependencyPath="getDependencyPath"}(l||(l={})),function(e){e.IPC="ipc",e.WS="ws"}(g||(g={}));const f=0,p=e=>{try{return JSON.parse(e)}catch(e){return null}},y="undefined"!=typeof window,m=(e,t,n,r="srgb")=>{let a;return a=e instanceof Uint8ClampedArray?e:new Uint8ClampedArray(e),{data:a,width:t,height:n,colorSpace:r,_kemuType:o.ImageData}};var h={id:"widgets",retry:1500,silent:!0,rawBuffer:!0,appspace:"kemu.",encoding:"hex"};const I={protocolPrefix:4,protocolVersion:1,jsonLength:4,binaryLength:4,fromServiceId:4,toServiceId:4,sentAt:8},v={protocolPrefix:4,txtLength:4},S=Object.values(I).reduce(((e,t)=>e+t),0),b=Object.values(v).reduce(((e,t)=>e+t),0),w=["width","height","colorSpace"],A=(e,t)=>{const n={},r=[];let a=0,i=Array.isArray(e)?[]:{};const o=(e,i)=>{const s=(e=>{const t="undefined"!=typeof Buffer&&e instanceof Buffer,n=e instanceof ArrayBuffer,r=e instanceof Uint8ClampedArray,a=e instanceof Uint8Array,i=e instanceof Int8Array;return t?"Buffer":n?"ArrayBuffer":r?"Uint8ClampedArray":a?"Uint8Array":i?"Int8Array":null})(e);if(!s){if(Array.isArray(e)){const t=[];for(let n=0;n<e.length;n++)t[n]=o(e[n],`${i}[${n}]`);return t}if("object"==typeof e){const t={},n=(e=>{const t=e instanceof Int16Array,n=e instanceof Uint16Array,r=e instanceof Int32Array,a=e instanceof Uint32Array,i=e instanceof Float32Array,o=e instanceof Float64Array,s=e instanceof BigInt64Array,c=e instanceof BigUint64Array;return t?"Int16Array":n?"Uint16Array":r?"Int32Array":a?"Uint32Array":i?"Float32Array":o?"Float64Array":s?"BigInt64Array":c?"BigUint64Array":null})(e);if(n)throw new Error(`Unsupported binary type [${n}] at path "${i}"`);for(const n in e)Object.hasOwn(e,n)||w.includes(n)||console.warn(`Allowing inherited property: ${n} from path: ${i}`),t[n]=o(e[n],`${i.length?`${i}.`:""}${n}`);return t}return e}n[i]={index:a,length:e.byteLength,binaryType:s},"Buffer"===t?r.push(Buffer.from(e)):"ArrayBuffer"===s?r.push(e):r.push(e.buffer),a+=e.byteLength};i=o(e,"");let s=null;if(r.length>1)if("ArrayBuffer"===t){const e=r.reduce(((e,t)=>e+t.byteLength),0),t=new Uint8Array(e);let n=0;for(let e=0;e<r.length;e++)t.set(new Uint8Array(r[e]),n),n+=r[e].byteLength;s=t.buffer}else{s=Buffer.concat(r)}else 1===r.length&&(s=r[0]);return s?{map:n,combinedData:s,sourceCopy:i}:null},B=(e,t,n,r)=>{const a=t.match(/(\[\d+\])|([^[\].]+)/g)||[];let i=e;for(let e=0;e<a.length;e++){let t=a[e];const r=t.startsWith("[")&&t.endsWith("]"),o=e===a.length-1;if(r){t=t.slice(1,-1);const r=parseInt(t,10);if(!Array.isArray(i))throw new Error(`Expected an array at key "${a.slice(0,e).join(".")}" but found an object.`);o?i[r]=n:(i[r]||(i[r]=a[e+1].startsWith("[")?[]:{}),i=i[r])}else o?i[t]=n:(i[t]||(i[t]=a[e+1].startsWith("[")?[]:{}),i=i[t])}return e},L=(e,t,n)=>{const r="undefined"!=typeof Buffer,a=t instanceof Uint8Array;for(const i in n)if(Object.hasOwn(n,i)){const{index:o,length:s,binaryType:c}=n[i];let d=null;if(r&&t instanceof Buffer)switch(c){case"Buffer":d=t.subarray(o,o+s);break;case"ArrayBuffer":d=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s);break;case"Uint8Array":d=new Uint8Array(t.subarray(o,o+s));break;case"Uint8ClampedArray":d=new Uint8ClampedArray(t.subarray(o,o+s));break;case"Int8Array":d=new Int8Array(t.subarray(o,o+s))}else if(t instanceof ArrayBuffer||t instanceof Uint8Array)switch(c){case"Buffer":if(r){d=Buffer.from(t.slice(o,o+s));break}case"ArrayBuffer":d=a?t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength).slice(o,o+s):t.slice(o,o+s);break;case"Uint8Array":d=a?t.slice(o,o+s):new Uint8Array(t.slice(o,o+s));break;case"Uint8ClampedArray":d=new Uint8ClampedArray(t.slice(o,o+s));break;case"Int8Array":d=new Int8Array(t.slice(o,o+s))}d&&B(e,i,d)}return e},U=e=>a(e),E="KMSG",C="KCMD",D=U("klProtocol");var k={encode:(e,t,n)=>{const r={json:e.json},a=A(r.json,"Buffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=Buffer.from(s),d=c.byteLength,u=I.protocolPrefix+I.protocolVersion+I.jsonLength+I.binaryLength+I.fromServiceId+I.toServiceId+I.sentAt+d+o,l=Buffer.alloc(u),g=Date.now();let f=0;return l.write(E,f),f+=I.protocolPrefix,l.writeUInt8(1,f),f+=I.protocolVersion,l.writeUInt32LE(d,f),f+=I.jsonLength,l.writeUInt32LE(o,f),f+=I.binaryLength,l.writeUInt32LE(t,f),f+=I.fromServiceId,l.writeUInt32LE(n,f),f+=I.toServiceId,l.writeBigInt64LE(BigInt(g),f),f+=I.sentAt,c.copy(l,f),f+=d,i&&o&&i.copy(l,f),l},decodeHeader:e=>{let t=0;const n=e.toString("utf-8",t,I.protocolPrefix);if(t+=I.protocolPrefix,n!==E)return null;if(e.byteLength<S)return D(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const r=e.readUInt8(t);t+=I.protocolVersion;const a=e.readUInt32LE(t);t+=I.jsonLength;const i=e.readUInt32LE(t);t+=I.binaryLength;const o=e.readUInt32LE(t);t+=I.fromServiceId;const s=e.readUInt32LE(t);t+=I.toServiceId;const c=e.readBigInt64LE(t);t+=I.sentAt;const d=a+i,u=e.subarray(t,t+d),l=e.subarray(0,S);let g=null;return e.byteLength-S-a-i>0&&(g=e.subarray(S+a+i)),{header:{protocolVersion:r,jsonLength:a,binaryLength:i,fromServiceId:o,toServiceId:s,sentAt:new Date(Number(c)),packages:[u],headerPackage:l},remaining:g}},decodeFullKlMessage:e=>{const t=Buffer.concat(e.packages),n=t.subarray(0,e.jsonLength).toString(),r=t.subarray(e.jsonLength,e.jsonLength+e.binaryLength),a=p(n);if(!a?.json)return D("Invalid JSON in KL message"),null;a.jsonBinaryMap&&r.byteLength&&L(a.json,r,a.jsonBinaryMap);const i=Buffer.concat([e.headerPackage,t]);let o=i,s=null;const c=S+e.jsonLength+e.binaryLength;return i.byteLength>c&&(s=i.subarray(c),o=i.subarray(0,c)),{message:{json:a.json,rawMessage:o},remaining:s}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<S)return D("Invalid Header Size"),e;let n=0;return n+=I.protocolPrefix,n+=I.protocolVersion,n+=I.jsonLength,n+=I.binaryLength,void 0!==t.fromServiceId&&e.writeUInt32LE(t.fromServiceId,n),n+=I.fromServiceId,void 0!==t.toServiceId&&e.writeUInt32LE(t.toServiceId,n),e},encodeCommand:e=>{let t=0;const n=Buffer.from(e),r=n.byteLength,a=b+r,i=Buffer.alloc(a);return i.write(C,t),t+=v.protocolPrefix,i.writeUint32LE(r,t),t+=v.txtLength,n.copy(i,t),i},decodeCommand:e=>{let t=0;if(e.byteLength<b)return{command:null};const n=e.toString("utf-8",t,v.protocolPrefix);if(t+=v.protocolPrefix,n!==C)return{command:null};const r=e.readUInt32LE(t);t+=v.txtLength;const a=e.toString("utf-8",t,t+r),i=e.byteLength-b-r;let o=null;i>0&&(o=e.subarray(b+r));let s=0;return i<0&&(s=Math.abs(i)),{command:a,remainingData:o,missing:s}}};const j="KMSG",P="KCMD",x=U("klProtocol"),R=new TextEncoder;var $={encode:(e,t,n)=>{const r={json:e.json},a=A(e.json,"ArrayBuffer"),i=a?.combinedData;a&&(r.jsonBinaryMap=a.map,r.json=a.sourceCopy);const o=i?i.byteLength:0,s=JSON.stringify(r),c=R.encode(s),d=c.byteLength,u=new ArrayBuffer(I.protocolPrefix+I.protocolVersion+I.jsonLength+I.binaryLength+I.fromServiceId+I.toServiceId+I.sentAt+d+o),l=new DataView(u),g=new Uint8Array(u),f=Date.now();let p=0;for(let e=0;e<4;++e)g[p++]=j.charCodeAt(e);return l.setUint8(p,1),p+=I.protocolVersion,l.setUint32(p,d,!0),p+=I.jsonLength,l.setUint32(p,o,!0),p+=I.binaryLength,l.setUint32(p,t,!0),p+=I.fromServiceId,l.setUint32(p,n,!0),p+=I.toServiceId,l.setBigInt64(p,BigInt(f),!0),p+=I.sentAt,g.set(c,p),p+=d,i&&o&&g.set(new Uint8Array(i),p),u},decodeHeader:e=>{const t=new DataView(e);let n=0,r="";for(let e=0;e<I.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==j)return null;if(e.byteLength<S)return x.log(`Received a Partial Header with ${e.byteLength} bytes. Waiting for more data.`),{partialHeader:!0,remaining:null};const a=t.getUint8(n);n+=I.protocolVersion;const i=t.getUint32(n,!0);n+=I.jsonLength;const o=t.getUint32(n,!0);n+=I.binaryLength;const s=t.getUint32(n,!0);n+=I.fromServiceId;const c=t.getUint32(n,!0);n+=I.toServiceId;const d=t.getBigInt64(n,!0);n+=I.sentAt;const u=i+o,l=e.slice(n,n+u),g=new Uint8Array(e,0,S);let f=null;if(e.byteLength-S-i-o>0){f=new Uint8Array(e,S+i+o).slice().buffer}return{header:{protocolVersion:a,jsonLength:i,binaryLength:o,fromServiceId:s,toServiceId:c,sentAt:new Date(Number(d)),packages:[l],headerPackage:g.slice().buffer},remaining:f}},decodeFullKlMessage:e=>{const t=e.packages.reduce(((e,t)=>e+t.byteLength),0),n=new Uint8Array(t);let r,a=0;for(const t of e.packages)r=new Uint8Array(t),n.set(r,a),a+=r.byteLength;const i=(new TextDecoder).decode(n.subarray(0,e.jsonLength)),o=n.subarray(e.jsonLength,e.jsonLength+e.binaryLength),s=p(i);if(!s?.json)return x.log("Invalid JSON in KL message"),null;s.jsonBinaryMap&&o.byteLength&&L(s.json,o,s.jsonBinaryMap);const c=new Uint8Array(e.headerPackage.byteLength+n.byteLength);c.set(new Uint8Array(e.headerPackage),0),c.set(n,e.headerPackage.byteLength);let d=c,u=null;const l=S+e.jsonLength+e.binaryLength;return c.byteLength>l&&(u=c.subarray(l),d=c.subarray(0,l)),{message:{json:s.json,...o.length?{binaryData:o.buffer}:{},rawMessage:d.buffer},remaining:u?.buffer??null}},patchEncodedHeader:(e,t)=>{if(null==t.fromServiceId&&void 0===t.toServiceId)return e;if(e.byteLength<S)return x("Invalid Header Size"),e;let n=0;n+=I.protocolPrefix,n+=I.protocolVersion,n+=I.jsonLength,n+=I.binaryLength;const r=new DataView(e);return void 0!==t.fromServiceId&&r.setUint32(n,t.fromServiceId,!0),n+=I.fromServiceId,void 0!==t.toServiceId&&r.setUint32(n,t.toServiceId,!0),e},encodeCommand:e=>{let t=0;const n=R.encode(e),r=n.byteLength,a=new ArrayBuffer(b+r),i=new DataView(a),o=new Uint8Array(a);for(let e=0;e<4;++e)o[t++]=P.charCodeAt(e);return i.setUint32(t,r,!0),t+=v.txtLength,o.set(n,t),a},decodeCommand:e=>{const t=new DataView(e);let n=0;if(e.byteLength<b)return{command:null};let r="";for(let e=0;e<v.protocolPrefix;++e)r+=String.fromCharCode(t.getUint8(n++));if(r!==P)return{command:null};const a=t.getUint32(n,!0);n+=v.txtLength;const i=e.byteLength-b-a,o=new Uint8Array(e,n,Math.min(a,e.byteLength-b)),s=(new TextDecoder).decode(o);let c=null;i>0&&(c=e.slice(b+a));let d=0;return i<0&&(d=Math.abs(i)),{command:s,remainingData:c,missing:d}}};const M=U("klTransmissionManager");let N=k;y&&(N=$);var O=N;let T,F,H,K,G=null;const V=(()=>{const e=(t,n,r,a)=>{let i=n,o=null;const s=t instanceof ArrayBuffer;if(M(`RAW: ${t.toString()}`),!i||i.partialHeaderData){let c;if(s?(c=i?.partialHeaderData?new Uint8Array([...new Uint8Array(i.partialHeaderData),...new Uint8Array(t)]).buffer:t,o=$.decodeHeader(c)):(c=i?.partialHeaderData?Buffer.concat([i.partialHeaderData,t]):t,o=k.decodeHeader(c)),!o){const{command:t,missing:i,remainingData:o}=s?$.decodeCommand(c):k.decodeCommand(c);return t?a({command:t,complete:!0,rawMessage:c}):M(i?`ERROR: Missing ${i} bytes to complete the command. This partial command will be aborted.`:`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`),o?(M(`${o.byteLength} bytes remain after processing command. Re-analyzing...`),e(o,n,r,a)):void 0}if(o.partialHeader)return i={firstPackageAt:Date.now(),partialHeaderData:c},r(i);if(!o.header)return M(`ERROR: Invalid state, message was decoded without a header or partial header data. Discarding ${c.byteLength} bytes`);const d=o.header;i={firstPackageAt:Date.now(),header:{...d,totalBytesReceived:d.packages[0].byteLength,totalBytesExpected:d.binaryLength+d.jsonLength,remaining:o.remaining}},r(i)}else i.header&&i.header.totalBytesReceived<i.header.totalBytesExpected&&(i.header.packages.push(t),i.header.totalBytesReceived+=t.byteLength,r(i));if(i.header&&i.header.totalBytesReceived>=i.header.totalBytesExpected){const t=Date.now()-i.header.sentAt.getTime(),n=Date.now()-i.firstPackageAt;M(`Received ${i.header.totalBytesReceived} of ${i.header.totalBytesExpected} expected in ${t} ms, elapsed since first package: ${n}ms`);const o=s?$.decodeFullKlMessage(i.header):k.decodeFullKlMessage(i.header),c=i.header.totalBytesReceived,d=i.header.remaining;r(null),o&&a({klMessage:o.message,complete:!0,sourceServiceId:i.header.fromServiceId,targetServiceId:i.header.toServiceId,rawMessage:o.message.rawMessage});let u=d;if(o?.remaining&&(u=s?d?((e,t)=>{const n=e.byteLength+t.byteLength,r=new ArrayBuffer(n),a=new Uint8Array(e),i=new Uint8Array(t),o=new Uint8Array(r);return o.set(a),o.set(i,a.length),r})(d,o.remaining):o.remaining:d?Buffer.concat([d,o.remaining]):o.remaining),u)return M(`${u.byteLength} bytes remaining after processing message with ${c} bytes of data. Re-analyzing...`),e(u,null,r,a)}};return e})(),_=U("ipcClient"),W=e=>{const t=h.id;r.of[t].emit(e)};var J,z={connect:e=>{h.id=e?.id||h.id,h.appspace=e?.appSpace||h.appspace,r.config={...r.config,...h};const t=h.id;r.connectTo(t,(()=>{r.of[t].on("connect",(()=>{_("Connected to server"),G=null,F&&F()})),r.of[t].on("data",(e=>{V(e,G,(e=>G=e),(e=>{if(e.complete)return e.command?(_(`Received command: ${e.command}`),void(T&&T(e.command))):void(e.klMessage&&H&&H({send:W,transmission:{sourceServiceId:e.sourceServiceId??-1,targetServiceId:e.targetServiceId??-1,rawMessage:e.rawMessage},json:e.klMessage.json}))}))})),r.of[t].on("disconnect",(()=>{_(`Disconnected from ${t}`),G=null,K&&K()}))}))},sendCommand:e=>{const t=h.id,n=O.encodeCommand(e);r.of[t].emit(n)},sendBuffer:W,onCommand:e=>T=e,onMessageReceived:e=>H=e,onClientConnected:e=>F=e,onClientDisconnected:e=>K=e};!function(e){e.FunctionNotFound="FNC_NOT_FOUND",e.ParentEventCallbackError="PARENT_EVENT_CALLBACK_ERROR"}(J||(J={}));const q=3e4;let Q=Math.ceil(Date.now()/1e3);function X(e){const t={};let n=console.log;const r={};let a=e||String(Date.now());const i={},o=e=>!i[e],s=(e,t,n,r,a,i)=>{let s=y?new ArrayBuffer(0):Buffer.alloc(0);const c={json:{functionName:e,args:i.success?i.success:[i],messageId:t,type:i.success?"response":"error"}};return o(r)&&(s=O.encode(c,n,r)),a(s,{msg:c,sourceServiceId:n,targetServiceId:r})};return{setLogger:e=>{n=e},processMessage:(e,a,i,o)=>{if(!o)return!1;const c=o;if(t[c.messageId]){const e=t[c.messageId];return e&&(clearTimeout(e.timer),e.fulfilled||(e.fulfilled=!0,"response"===c.type?e.resolve(c.args):"error"===c.type&&e.reject(c.args[0])),delete t[c.messageId]),!0}if("execute"!==c.type&&n&&n(`No pending execution found for message id "${c.messageId}"`),"execute"===c.type){const t=r[c.functionName];if(t){const n=e=>{s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,e)};t({transport:e,args:c.args,reply:n,messageId:c.messageId,sourceServiceId:i.sourceServiceId,send:a})}else{const e=`Function "${c.functionName}" not found.`;n&&n(e),s(c.functionName,c.messageId,i.targetServiceId,i.sourceServiceId,a,{error:e,errCode:"FNC_NOT_FOUND"})}return!0}return!1},execute:async(e,r,i,s,c,d)=>{if(!i){const e="No send buffer function provided.";throw n&&n(e),e}Q+=1;const u=`${a}-${Q}-exec-${e.substring(0,10)}`,l={messageId:u,functionName:e,send:i,sourceServiceId:s,targetServiceId:c,args:r||[],fulfilled:!1,resolve:()=>{},reject:()=>{}};l.promise=new Promise(((e,t)=>{l.resolve=e,l.reject=t}));let g=y?new ArrayBuffer(0):Buffer.alloc(0);const f={json:{functionName:e,args:r,messageId:u,type:"execute"}};o(c)&&(g=O.encode(f,s,c)),t[u]=l,n&&n(`Calling remote function "${e}" with message id "${u}"`);const p="true"===process.env.NO_INVOKE_TIMEOUT;return d?.async?(l.fulfilled=!0,l.resolve([void 0]),delete t[u]):0===d?.timeout||p||(l.timer=setTimeout((()=>{n&&n(`Remote function ${u} timed out`);const r=t[u];r&&!r.fulfilled&&(r.fulfilled=!0,l.reject(`Function ${e} Timed out`)),delete t[u]}),d?.timeout||q)),i(g,{sourceServiceId:s,targetServiceId:c,msg:f}),l.promise},sendResponse:s,registerFunction:(e,t)=>{r[e]=t},getTransportSendFunction:e=>{const n=t[e];return n?n.send:null},setServiceName:e=>{a=e},getPendingExecutions:()=>t,rejectAllPending:e=>{Object.keys(t).forEach((n=>{const r=t[n];r&&!r.fulfilled&&(clearTimeout(r.timer),r.fulfilled=!0,r.reject(e),delete t[n])}))},broadcast:(e,t,r,i)=>{Q+=1;const s=`${a}-${Q}-multicast-${e.substring(0,10)}`;let c=y?new ArrayBuffer(0):Buffer.alloc(0);const d={json:{functionName:e,args:t,messageId:s,type:"execute"}};let u=o(r[0].serviceId);u&&(c=O.encode(d,i,r[0].serviceId));for(let t=0;t<r.length;t++)try{const a=r[t];n&&n(`Broadcasting function "${e}" with message id "${s}" to client [${a.serviceId}]`),0!==t&&(u=o(a.serviceId),u&&(c=O.patchEncodedHeader(c,{toServiceId:a.serviceId}))),a.sendFn(c,{msg:d,sourceServiceId:i,targetServiceId:a.serviceId})}catch(e){n&&n(`Error broadcasting to client at index ${t}`)}},disableServiceEncoding:(e,t)=>{i[e]=t}}}const Y=U("kemuWidgetService"),Z=t(process.argv.slice(2));function ee(t){const r={},a=process.env.KEMU_WIDGET_SESSION_ID;let i,o,s,c,f=!1;const y={};let m,h,I,v,S,b,w,A,B=null;const L=new X;L.setLogger(Y);r.start=async(r,c)=>{const d=r||n.resolve(n.dirname(process.argv[1]),"manifest.json");s=n.dirname(d);const l=await e(d,"utf-8"),y=p(l);if(!y)throw new Error("Error parsing manifest file.");let m;if(y.inputs||(y.inputs=[]),y.outputs||(y.outputs=[]),y.widgetUI)try{m=await e(n.join(s,"widgetUI.js"))}catch(e){Y(`Error loading widgetUI file ${y.name}: ${e}`)}if(y.svgIcon)try{const t=await e(n.join(s,y.svgIcon),"utf-8");y.svgIcon=t}catch(e){Y(`Error loading icon for service ${y.name}: ${e}`)}o=((e,t,n)=>({...e,path:t,...e.widgetUI&&n?.widgetUIContents?{widgetUIContents:n.widgetUIContents}:{}}))(y,s,{widgetUIContents:m}),f=o.name.startsWith("test."),o.path=s,o.internal=Z.internal||!1,f?Y("Starting Kemu Service in Dev mode"):((e=>{const t=e||Z.sessionId||a;if(!t)throw new Error("Missing sessionId. Expected service to be launched with a sessionId as first argument, or the KEMU_WIDGET_SESSION_ID environment variable to be set.");i=parseInt(String(t))})(c),Y(`Starting Kemu Service with session id: ${i}`)),L.setServiceName(`${o.name}_${o.version}`),z.onCommand(U),z.onMessageReceived((({json:e,transmission:t})=>L.processMessage(g.IPC,z.sendBuffer,t,e))),L.registerFunction(u.OnParentEvent,C),L.registerFunction(u.GetDefaultState,E),L.registerFunction(u.UIEvent,P),L.registerFunction(u.InitializeInstance,D),L.registerFunction(u.TerminateInstance,k),L.registerFunction(u.KemuComposerDisconnected,j),z.onClientConnected((()=>{A&&A()})),z.onClientDisconnected((()=>{f&&(i=void 0)})),z.connect({appSpace:Z.ipcSpace||t?.ipc?.appSpace,id:Z.ipcId||t?.ipc?.id})};const U=e=>{((e,t)=>{const n=d.SocketAcknowledge,r=d.IpcAcknowledge,a=e.startsWith(n),i=e.startsWith(r);if(a||i){const i=e.split(a?n:r),o=parseInt(i[1]);return t&&t(o),o}})(e,(e=>{z.sendCommand(((e,t)=>`${d.AcknowledgeResponse}${e}:${t||""}`)(e,i||void 0)),!i&&f&&(Y("Dev mode detected, assuming service session id from ack request:",e),i=e)})),((e,t)=>{e===d.BroadcastStart&&t()})(e,(()=>{I&&I()})),((e,t)=>{e===d.BroadcastEnd&&t()})(e,(()=>{v&&v()})),((e,t)=>{e===d.SendManifest&&t()})(e,(()=>{Y("Sending manifest to hub"),i?L.execute(u.ServiceManifest,[{...o,devMode:f}],z.sendBuffer,i,0,{async:!0}):Y("Service session id is not set. Cannot send manifest.")})),((e,t)=>{if(e.startsWith(d.AssumeSession)){const n=e.split(d.AssumeSession);return t(parseInt(n[1])),!0}})(e,(e=>{i=e,Y(`Assumed session id ${e}`)}))},E=async e=>{if(h){const t=await h();return e.reply({success:[t]})}return e.reply({success:[{}]})},C=async e=>{if(!m)return Y("No onParentEvent callback defined. Skipping parent event."),e.reply({success:[]});const t=e.args[0],{source:n,target:r,data:a,recipe:o,currentState:s,targetVariantId:c,eventContext:d,currentPath:l,eventId:g}=t;if(!i)return void Y("Service session id is not set. Cannot process parent event.");if(!n||!r||!a)return e.reply({error:"Invalid arguments, expected [source, target, data, context]"});const f=z.sendBuffer,p=async t=>L.execute(u.SetOutputs,[t],f,i,e.sourceServiceId,{timeout:0}),y={currentState:s,type:r.widgetType,widgetId:r.widgetId,variantId:c,recipeId:o.poolId,recipeName:o.name,recipe:o,setState:async t=>{const n={widgetId:r.widgetId,variantId:c,recipeId:o.poolId,newState:t};return L.execute(u.SetState,[n],f,i,e.sourceServiceId)},setOutputs:async(e,t)=>{const n={widgetId:r.widgetId,recipeId:o.poolId,outputs:e,finalState:t,currentPath:l};await p(n)},setOutputsWithContext:async e=>{const t={...e,widgetId:r.widgetId,recipeId:o.poolId,currentPath:l};await p(t)}};Y(`Invoking user-defined onParentEvent callback for event id "${e.messageId}"`),await m({data:a,source:n,target:r,eventContext:d,currentPath:l,eventId:g},y).then((()=>{Y(`Replying SUCCESS to event id "${e.messageId}"`),e.reply({success:[]})})).catch((t=>{const n="string"==typeof t?t:t.message||t;Y(`Error invoking onParentEvent callback: ${n}`),e.reply({error:n,errCode:"PARENT_EVENT_CALLBACK_ERROR"})}))},D=async e=>{const[{currentState:t,widgetId:n,variantId:r,recipeType:a,currentDependencies:i,kemuApiKey:o,recipe:s}]=e.args;if(o&&(c=o),y[n]={currentRecipeId:s.poolId,variantId:r,currentSourceServiceId:e.sourceServiceId},S){const c=[],d={currentState:t,recipeId:s.poolId,recipeName:s.name,recipe:{uuid:s.uuid,poolId:s.poolId,name:s.name,type:s.type,version:s.version,authorId:s.authorId,dbId:s.dbId},widgetId:n,variantId:r,recipeType:a,currentDependencies:i||{},kemuApiKey:o,secrets:{requestAccess:e=>{c.push(...e)}}},u=await S(d);e.reply({success:[u,c]})}else e.reply({error:"Not implemented",errCode:"FNC_NOT_FOUND"})},k=async e=>{if(b){const[{currentState:t,recipe:n,widgetId:r,variantId:a}]=e.args,i={currentState:t,recipeId:n.poolId,recipe:n,widgetId:r,variantId:a};await b(i),delete y[r]}e.reply({success:[]})},j=async e=>{if(console.log("Kemu Composer disconnected event: ",e),e.reply({success:[]}),w){const[t]=e.args;t.recipe&&await w(t)}},P=async e=>{if(B)try{const t=await B.apply(void 0,e.args);return e.reply({success:[t]})}catch(t){const n="string"==typeof t?t:JSON.stringify(t);return Y(`Error invoking UI Event handler: ${n}`),e.reply({error:n})}e.reply({error:"UI Events are not supported in this service."})},x=async e=>{if(!o.eventEmitter)throw new Error("This service does not support broadcasting events. Please set `eventEmitter` to true in your manifest file.");if(i)return L.execute(u.BroadcastEvent,e,z.sendBuffer,i,0,{async:!0});Y("Service session id is not set. Cannot broadcast event.")};r.broadcast=async(e,t)=>{const n=[{outputs:e,variantId:t,currentPath:[]}];await x(n)},r.broadcastEvent=async e=>{const t=[{outputs:e.outputs,variantId:e.variantId,eventContext:e.eventContext,targetRecipeId:e.targetRecipeId,targetRecipePoolId:e.targetRecipePoolId,targetWidgetId:e.targetWidgetId,currentPath:e.currentPath||[],eventId:e.eventId}];await x(t)},r.addDependencyPath=async(e,t,n)=>{if(!i)throw new Error("Not yet registered with the Hub");const r=y[n];if(!r.currentSourceServiceId||!r.currentRecipeId)throw new Error("Cannot invoke this method before initialization");const a={key:e,path:t,recipeId:r.currentRecipeId,widgetId:n};Y(`Adding dependency path for key "${e}" with path "${t}"`),await L.execute(l.SetDependencyPath,[a],z.sendBuffer,i,r.currentSourceServiceId)},r.getDependencyPath=async(e,t)=>{if(!i)throw new Error("Not yet registered with the Hub");const n=y[t];if(!n.currentSourceServiceId||!n.currentRecipeId)throw new Error("Cannot invoke this method before initialization");Y("Getting dependency path for key:",e);const r={key:e,recipeId:n.currentRecipeId,widgetId:t},[a]=await L.execute(l.GetDependencyPath,[r],z.sendBuffer,i,n.currentSourceServiceId);return Y("Dependency path response:",a),a},r.getUniqueId=async()=>{if(!i)throw new Error("Not yet registered with the Hub");const[e]=await L.execute(u.GetUniqueId,[],z.sendBuffer,i,0);return e},r.resolveRuntimeDependencyPath=e=>{if(!Z.recipePath)throw new Error("Cannot resolve runtime dependency without a recipe path. Missing [--recipePath] argument.");return n.resolve(Z.recipePath,e)},r.onGetDefaultState=e=>{h=e},r.onParentEvent=e=>{m=e},r.onTerminate=e=>{b=e},r.onKemuComposerDisconnected=e=>{w=e},r.onInitialize=e=>{S=e},r.onConnected=e=>{A=e},r.onStartBroadcast=e=>{I=e},r.onStopBroadcast=e=>{v=e},r.onUIEvent=e=>{B=e},r.secrets={read:async e=>{if(!i)throw new Error("Service session id is not set. Cannot read secret.");const t=[{recipeUuid:e.recipeUuid,secretNames:e.names}],[n]=await L.execute(u.GetRecipeDecryptedSecretsValues,t,z.sendBuffer,i,0);return n?.secrets||{}}},Z.internal&&(r.executeHubFunction=async(e,t,n)=>{if(i)return L.execute(e,t,z.sendBuffer,i,0,n);Y("Service session id is not set. Cannot execute hub function.")});const R=r;return R._getRemoteInvoker=()=>L,R.getHubConfig=async()=>{if(!i)throw new Error("Service session id is not set. Cannot execute hub function.");const e=await L.execute(u.GetHubConfig,[],z.sendBuffer,i,0);return e?.[0]&&!e[0].kemuApiKey&&c&&(e[0].kemuApiKey=c),e?.[0]},R.getEdgeApiKey=async()=>{if(f)return void console.warn("This method [getEdgeApiKey] is NOT available in dev mode");if(!i)throw new Error("Service session id is not set. Cannot execute hub function.");const e=await L.execute(u.GetDecryptedEdgeApiKey,[],z.sendBuffer,i,0);return e?.[0]},r}export{o as DataType,f as KemuHubServiceId,m as createImageDataLike,ee as default};
@@ -70,6 +70,8 @@ var KemuHubFunctions;
70
70
  KemuHubFunctions["BroadcastEvent"] = "broadcastEvent";
71
71
  KemuHubFunctions["HubBroadcastEvent"] = "hubBroadcastEvent";
72
72
  KemuHubFunctions["ServiceManifest"] = "serviceManifest";
73
+ KemuHubFunctions["SendToRecipe"] = "sendToRecipe";
74
+ KemuHubFunctions["KemuComposerDisconnected"] = "kemu-composer-disconnected";
73
75
  KemuHubFunctions["GetState"] = "getState";
74
76
  KemuHubFunctions["SetState"] = "setState";
75
77
  KemuHubFunctions["SetOutputs"] = "setOutputs";
@@ -85,6 +87,13 @@ var KemuHubFunctions;
85
87
  KemuHubFunctions["GetFileContentFromCacheId"] = "getFileContentFromCacheId";
86
88
  KemuHubFunctions["GetDecryptedEdgeApiKey"] = "getDecryptedEdgeApiKey";
87
89
  KemuHubFunctions["GetHubConfig"] = "getHubConfig";
90
+ KemuHubFunctions["GetRecipeDecryptedSecretsValues"] = "getRecipeDecryptedSecretsValues";
91
+ KemuHubFunctions["GetRecipeSecretMappings"] = "getRecipeSecretMappings";
92
+ KemuHubFunctions["AddRecipeSecretMapping"] = "addRecipeSecretMapping";
93
+ KemuHubFunctions["DeleteRecipeSecretMapping"] = "deleteRecipeSecretMapping";
94
+ KemuHubFunctions["GetHubSecrets"] = "getHubSecrets";
95
+ KemuHubFunctions["AddHubSecrets"] = "addHubSecrets";
96
+ KemuHubFunctions["DeleteHubSecret"] = "deleteHubSecret";
88
97
  })(KemuHubFunctions || (KemuHubFunctions = {}));
89
98
  var ServiceToServiceFunctions;
90
99
  (function (ServiceToServiceFunctions) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kemu-io/hs",
3
3
  "type": "module",
4
- "version": "0.6.7",
4
+ "version": "0.8.0",
5
5
  "description": "Kemu Hub Service - NodeJs library for creating Kemu Services",
6
6
  "author": "Kemu Pty Ltd",
7
7
  "main": "service.js",