Skip to content

Commit

Permalink
implement ShadowEnv.onMessageToView
Browse files Browse the repository at this point in the history
  • Loading branch information
spearwolf committed Jun 26, 2024
1 parent 036dfaf commit 2de9f97
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 26 deletions.
3 changes: 2 additions & 1 deletion packages/shadow-ents-e2e/public/mod-hello.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ function foo({entity, useProperty}) {
console.log('foo.xyz changed to', val);
});

entity.dispatchLocalEvent('helloFromFoo', {xyz: xyz()});
// entity.dispatchViewEvent('helloFromFoo', {xyz: xyz()});
entity.dispatchMessageToView('helloFromFoo', {xyz: xyz()});
}

export const shadowObjects = {
Expand Down
5 changes: 5 additions & 0 deletions packages/shadow-ents/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export const AppliedChangeTrail = 'appliedChangeTrail';
export const ImportedModule = 'importedModule';
export const Destroyed = 'destroyed';

/**
* The `messageToView` event is fired when the kernel receives a message from an entity (to its view component counterpart)
*/
export const MessageToView = 'messageToView';

export const WorkerLoadTimeout = 16000;
export const WorkerReadyTimeout = 16000; // TODO remove WorkerReadyTimeout
export const WorkerConfigureTimeout = 16000;
Expand Down
8 changes: 4 additions & 4 deletions packages/shadow-ents/src/entities/Entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,18 +195,18 @@ export class Entity extends Eventize {
}
}

dispatchEventToView(type: string, data?: unknown, transferables?: Transferable[]) {
dispatchMessageToView(type: string, data?: unknown, transferables?: Transferable[]) {
this.#kernel.dispatchMessageToView({uuid: this.#uuid, type, data, transferables});
}

dispatchLocalEvents(events: IComponentEvent[]) {
dispatchViewEvents(events: IComponentEvent[]) {
for (const {type, data} of events) {
this.emit(onViewEvent, type, data);
}
}

dispatchLocalEvent(type: string, data: unknown) {
this.dispatchLocalEvents([{type, data}]);
dispatchViewEvent(type: string, data: unknown) {
this.dispatchViewEvents([{type, data}]);
}

#getPropSignal<T = unknown>(key: string): SignalObject<T> {
Expand Down
14 changes: 5 additions & 9 deletions packages/shadow-ents/src/entities/Kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
type CompareFunc,
type SignalReader,
} from '@spearwolf/signalize';
import {ComponentChangeType} from '../constants.js';
import {ComponentChangeType, MessageToView} from '../constants.js';
import type {IComponentChangeType, IComponentEvent, ShadowObjectConstructor, ShadowObjectType, SyncEvent} from '../types.js';
import {Entity} from './Entity.js';
import {Registry} from './Registry.js';
Expand Down Expand Up @@ -41,12 +41,6 @@ enum ShadowObjectAction {
* Which shadow-objects are created is determined by the token.
*/
export class Kernel extends Eventize {
/**
* The `messageToView` event is fired when the kernel receives a message from an entity (to its view component counterpart)
* XXX kernel message event is not used yet
*/
static MessageToView = 'messageToView';

registry: Registry;

#entities: Map<string, EntityEntry> = new Map();
Expand Down Expand Up @@ -209,7 +203,7 @@ export class Kernel extends Eventize {
}

dispatchEventsToEntity(uuid: string, events: IComponentEvent[]): void {
this.getEntity(uuid)?.dispatchLocalEvents(events);
this.getEntity(uuid)?.dispatchViewEvents(events);
}

changeProperties(uuid: string, properties: [string, unknown][]): void {
Expand All @@ -229,7 +223,9 @@ export class Kernel extends Eventize {
}

dispatchMessageToView(message: MessageToViewEvent): void {
this.emit(Kernel.MessageToView, message);
queueMicrotask(() => {
this.emit(MessageToView, message);
});
}

/**
Expand Down
4 changes: 4 additions & 0 deletions packages/shadow-ents/src/entities/ShadowObjectsGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ The entity reference. The entity is the logical container for the shadow objects

_TODO:_ describe entity events

> **entity.uuid:** _string_
The uuid of the entity. which is also the uuid of the [view component](../view/ViewComponent.md).

> **onDestroy:** `(callback: () => any)`
_TODO:_ add description
Expand Down
3 changes: 3 additions & 0 deletions packages/shadow-ents/src/view/IShadowObjectEnvProxy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type {MessageToViewEvent} from '../core.js';
import type {ChangeTrailType} from '../types.js';

export interface IShadowObjectEnvProxy {
Expand All @@ -8,4 +9,6 @@ export interface IShadowObjectEnvProxy {
applyChangeTrail(data: ChangeTrailType): Promise<void>;

destroy(): void;

onMessageToView?: (event: Omit<MessageToViewEvent, 'transferables'>) => any;
}
12 changes: 10 additions & 2 deletions packages/shadow-ents/src/view/LocalShadowObjectEnv.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ShadowObjectsExport} from '../constants.js';
import {Kernel} from '../entities/Kernel.js';
import {MessageToView, ShadowObjectsExport} from '../constants.js';
import {Kernel, type MessageToViewEvent} from '../entities/Kernel.js';
import type {Registry} from '../entities/Registry.js';
import {importModule} from '../entities/importModule.js';
import {toUrlString} from '../toUrlString.js';
Expand All @@ -18,6 +18,14 @@ export class LocalShadowObjectEnv implements IShadowObjectEnvProxy {

constructor(registry?: Registry) {
this.kernel = new Kernel(registry);

this.kernel.on(MessageToView, (message: MessageToViewEvent) => {
if ((this as IShadowObjectEnvProxy).onMessageToView != null) {
const {type, uuid} = message;
const data = structuredClone(message.data, {transfer: message.transferables});
(this as IShadowObjectEnvProxy).onMessageToView({type, uuid, data});
}
});
}

start(): Promise<void> {
Expand Down
12 changes: 8 additions & 4 deletions packages/shadow-ents/src/view/RemoteWorkerEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Destroyed,
ImportedModule,
Loaded,
MessageToView,
WorkerChangeTrailTimeout,
WorkerConfigureTimeout,
WorkerDestroyTimeout,
Expand Down Expand Up @@ -65,7 +66,7 @@ export class RemoteWorkerEnv implements IShadowObjectEnvProxy {

return this.workerLoaded.then(() => {
if (this.isDestroyed) {
throw 'RemoteWorkerEnv: worker was destoyed';
throw 'RemoteWorkerEnv: worker was destroyed';
}
return undefined;
});
Expand All @@ -77,7 +78,7 @@ export class RemoteWorkerEnv implements IShadowObjectEnvProxy {
await waitForMessageOfType(worker, Loaded, WorkerLoadTimeout);

if (this.isDestroyed) {
throw 'RemoteWorkerEnv: worker was destoyed';
throw 'RemoteWorkerEnv: worker was destroyed';
}

worker.addEventListener('message', this.onMessageFromWorker.bind(this));
Expand All @@ -93,8 +94,11 @@ export class RemoteWorkerEnv implements IShadowObjectEnvProxy {
}

onMessageFromWorker(event: MessageEvent) {
// TODO implement onMessageFromWorker
console.debug('RemoteWorkerEnv: message from worker', event);
if (event.data?.type === MessageToView) {
(this as IShadowObjectEnvProxy).onMessageToView?.(event.data.data);
} else {
console.debug('RemoteWorkerEnv: message from worker', event);
}
}

applyChangeTrail(changeTrail: ChangeTrailType): Promise<void> {
Expand Down
9 changes: 9 additions & 0 deletions packages/shadow-ents/src/view/ShadowEnv.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {eventize, type EventizeApi} from '@spearwolf/eventize';
import {createEffect, type SignalReader} from '@spearwolf/signalize';
import {signal, signalReader} from '@spearwolf/signalize/decorators';
import type {MessageToViewEvent} from '../core.js';
import type {ComponentContext} from './ComponentContext.js';
import type {IShadowObjectEnvProxy} from './IShadowObjectEnvProxy.js';

Expand Down Expand Up @@ -69,6 +70,10 @@ export class ShadowEnv {
const prevProxy = this.#shaObjEnvProxy;
this.#shaObjEnvProxy = proxy ?? undefined;

if (this.#shaObjEnvProxy) {
this.#shaObjEnvProxy.onMessageToView = this.#onMessageToView.bind(this);
}

if (prevProxy) {
prevProxy.destroy();
}
Expand Down Expand Up @@ -124,4 +129,8 @@ export class ShadowEnv {
}
}
}

#onMessageToView(event: Omit<MessageToViewEvent, 'transferables'>) {
console.log('ShadowEnv: onMessageToView', event.type, event.data);
}
}
15 changes: 9 additions & 6 deletions packages/shadow-ents/src/worker/MessageRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {
Destroyed,
ImportedModule,
Init,
MessageToView,
Ready,
ShadowObjectsExport,
} from '../constants.js';
import {Kernel} from '../entities/Kernel.js';
import {Kernel, type MessageToViewEvent} from '../entities/Kernel.js';
import {shadowObjects} from '../entities/ShadowObject.js';
import {importModule} from '../entities/importModule.js';
import {toUrlString} from '../toUrlString.js';
Expand Down Expand Up @@ -47,11 +48,7 @@ export class MessageRouter {

this.postMessage = options?.postMessage ?? self.postMessage.bind(self);

this.kernel.on(Kernel.MessageToView, (event) => {
console.log('[MessageRouter] TODO messageToView', event);
// TODO postMessage to view-component
});
// TODO unsubscribe
this.kernel.on(MessageToView, 'onMessageToView', this);
}

route(event: MessageEvent) {
Expand All @@ -78,6 +75,11 @@ export class MessageRouter {
}
}

onMessageToView(event: MessageToViewEvent) {
const {transferables: transfer, ...data} = event;
this.postMessage({type: MessageToView, data}, {transfer});
}

async #configure(data: ConfigurePayloadData) {
try {
const module = await import(/* @vite-ignore */ toUrlString(data.importModule));
Expand Down Expand Up @@ -125,6 +127,7 @@ export class MessageRouter {

#onDestroy(data: any) {
console.debug('[MessageRouter] on destroy', data);
this.kernel.off(this);
this.#importedModules.clear();
this.postMessage({type: Destroyed});
}
Expand Down

0 comments on commit 2de9f97

Please sign in to comment.