Skip to content

Commit

Permalink
add syncShadowObjects() to shae elements
Browse files Browse the repository at this point in the history
  • Loading branch information
spearwolf committed Jul 4, 2024
1 parent bf2ff24 commit bfe82e7
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
12 changes: 12 additions & 0 deletions packages/shadow-ents/src/elements/ShaeElement.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {createSignal} from '@spearwolf/signalize';
import {GlobalNS} from '../constants.js';
import {toNamespace} from '../toNamespace.js';
import {ShadowEnv} from '../view/ShadowEnv.js';
import {readNamespaceAttribute} from './attr-utils.js';
import {ATTR_NS} from './constants.js';

Expand Down Expand Up @@ -47,6 +48,17 @@ export class ShaeElement extends HTMLElement {
}
}

#needsSyncShadowObjects = false;

syncShadowObjects() {
if (this.#needsSyncShadowObjects) return;
this.#needsSyncShadowObjects = true;
queueMicrotask(() => {
this.#needsSyncShadowObjects = false;
ShadowEnv.get(this.ns)?.sync();
});
}

#updateNs() {
this.ns$.set(readNamespaceAttribute(this));
}
Expand Down
3 changes: 3 additions & 0 deletions packages/shadow-ents/src/view/ComponentContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@ export class ComponentContext {
return globalThis.__shadowEntsContexts.get(ns)!;
} else {
const ctx = new ComponentContext();
ctx.ns = ns;
globalThis.__shadowEntsContexts.set(ns, ctx);
return ctx;
}
}

ns?: NamespaceType;

#components: Map<string, ViewInstance> = new Map();
#rootComponents: string[] = []; // we use an Array here and not a Set, because we want to keep the insertion order

Expand Down
41 changes: 37 additions & 4 deletions packages/shadow-ents/src/view/ShadowEnv.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import {Priority, eventize, type EventizeApi} from '@spearwolf/eventize';
import {createEffect, type SignalReader} from '@spearwolf/signalize';
import {createEffect, createSignal, type SignalReader} from '@spearwolf/signalize';
import {signal, signalReader} from '@spearwolf/signalize/decorators';
import {type MessageToViewEvent} from '../core.js';
import {type MessageToViewEvent, type NamespaceType} from '../core.js';
import {ComponentContext} from './ComponentContext.js';
import type {IShadowObjectEnvProxy} from './IShadowObjectEnvProxy.js';

declare global {
// eslint-disable-next-line no-var
var __shadowEnvs: Map<NamespaceType, ShadowEnv> | undefined;
}

export interface ShadowEnv extends EventizeApi {}

export class ShadowEnv {
static AfterSync = 'afterSync';
static ContextLost = 'contextLost';
static ContextCreated = 'contextCreated';

static get(ns: NamespaceType): ShadowEnv | undefined {
if (ns == null) return undefined;
return globalThis.__shadowEnvs?.get(ns);
}

#comCtx?: ComponentContext;
#shaObjEnvProxy?: IShadowObjectEnvProxy;
#syncScheduled = false;
#syncAfterContextCreated = false;
#whenReady!: Promise<ShadowEnv>;

readonly ns$ = createSignal<NamespaceType | undefined>();

@signal() accessor viewReady = false;
@signalReader() accessor viewReady$: SignalReader<boolean>;

Expand Down Expand Up @@ -61,7 +73,24 @@ export class ShadowEnv {

set view(ctx: ComponentContext | null | undefined) {
if (ctx !== this.#comCtx) {
if (this.#comCtx && this.#comCtx.ns && globalThis.__shadowEnvs) {
globalThis.__shadowEnvs.delete(this.#comCtx.ns);
}

this.#comCtx = ctx ?? undefined;

if (this.#comCtx && this.#comCtx.ns) {
globalThis.__shadowEnvs ??= new Map();
if (globalThis.__shadowEnvs.has(this.#comCtx.ns) && globalThis.__shadowEnvs.get(this.#comCtx.ns) !== this) {
console.warn(
'ShadowEnv: overwrite a namespace already in use',
this.#comCtx.ns,
globalThis.__shadowEnvs.get(this.#comCtx.ns),
);
}
globalThis.__shadowEnvs.set(this.#comCtx.ns, this);
}

this.viewReady = Boolean(ctx);
}
}
Expand Down Expand Up @@ -119,6 +148,12 @@ export class ShadowEnv {
return onSync;
}

destroy() {
this.envProxy?.destroy();
this.envProxy = undefined;
this.view = undefined;
}

async #syncNow() {
this.#syncScheduled = false;
if (this.isReady) {
Expand All @@ -139,6 +174,4 @@ export class ShadowEnv {
console.log('ShadowEnv: onMessageToView', event.type, event.data);
this.view?.dispatchMessage(event.uuid, event.type, event.data);
}

// TODO ShadowEnv#destroy()
}

0 comments on commit bfe82e7

Please sign in to comment.