Skip to content

Commit

Permalink
create new <shae-worker>
Browse files Browse the repository at this point in the history
  • Loading branch information
spearwolf committed Jun 28, 2024
1 parent 012ab4c commit 465577c
Show file tree
Hide file tree
Showing 15 changed files with 257 additions and 50 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"cSpell.words": [
"ents",
"plah",
"Shae",
"testresult",
"transferables"
]
Expand Down
14 changes: 14 additions & 0 deletions packages/shadow-ents-e2e/pages/shae-worker.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>shae-worker</title>
</head>
<body>
<shae-worker id="worker"></shae-worker>
<section id="tests"></section>
<script type="module" src="/src/shae-worker.js"></script>
</body>
</html>
44 changes: 0 additions & 44 deletions packages/shadow-ents-e2e/src/remote-worker-env.js

This file was deleted.

26 changes: 26 additions & 0 deletions packages/shadow-ents-e2e/src/shae-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {GlobalNS} from '@spearwolf/shadow-ents';
import '@spearwolf/shadow-ents/shae-worker.js';
import './style.css';
import {testAsyncAction} from './testAsyncAction.js';
import {testBooleanAction} from './testBooleanAction.js';

main();

async function main() {
const worker = document.getElementById('worker');

window.worker = worker;
console.log('shae-worker element', worker);

await testAsyncAction('shae-worker-whenDefined', () => customElements.whenDefined('shae-worker'));

const shadowEnv = worker.shadowEnv;
window.shadowEnv = shadowEnv;
console.log('shadowEnv', shadowEnv);

testBooleanAction('shae-worker-ns', () => worker.ns === GlobalNS);

await testAsyncAction('shadow-env-ready', async () => {
await shadowEnv.ready();
});
}
1 change: 1 addition & 0 deletions packages/shadow-ents-e2e/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ main {
}

#tests {
margin-top: 1rem;
margin-left: auto;
margin-right: auto;
display: grid;
Expand Down
6 changes: 6 additions & 0 deletions packages/shadow-ents/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,18 @@
"default": "./dist/src/shadow-local-env.js",
"types": "./dist/src/shadow-local-env.d.ts"
},
"./shae-worker.js": {
"default": "./dist/src/shae-worker.js",
"types": "./dist/src/shae-worker.d.ts"
},
"./shadow-worker.js": {
"default": "./dist/src/shadow-worker.js",
"types": "./dist/src/shadow-worker.d.ts"
}
},
"sideEffects": [
"build/src/view/ComponentContext.js",
"build/src/shae-worker.js",
"build/src/shadow-worker.js",
"build/src/shadow-entity.js",
"build/src/shadow-local-env.js",
Expand All @@ -65,6 +70,7 @@
"build/src/core.js",
"build/src/index.js",
"dist/src/view/ComponentContext.js",
"dist/src/shae-worker.js",
"dist/src/shadow-worker.js",
"dist/src/shadow-entity.js",
"dist/src/shadow-local-env.js",
Expand Down
1 change: 1 addition & 0 deletions packages/shadow-ents/package.override.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"src/core.js",
"src/index.js",
"src/view/ComponentContext.js",
"src/shae-worker.js",
"src/shadow-worker.js",
"src/shadow-entity.js",
"src/shadow-local-env.js",
Expand Down
3 changes: 2 additions & 1 deletion packages/shadow-ents/src/bundle.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import './shadow-entity.js';
import './shadow-env.js';
import './shadow-env-legacy.js';
import './shadow-env.js';
import './shadow-local-env.js';
import './shadow-worker.js';
import './shae-worker.js';

declare global {
// eslint-disable-next-line no-var
Expand Down
3 changes: 1 addition & 2 deletions packages/shadow-ents/src/elements/ShadowEntityElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class ShadowEntityElement extends HTMLElement {

this.getContextByType$$(ShadowElementType.ShadowEnv)!.get((env) => {
this.shadowEnvElement = env as unknown as IShadowEnvElementLegacy;
// this.componentContext = (env && (env as unknown as IShadowEnvElementLegacy).getComponentContext()) || undefined;
this.componentContext = (env && (env as unknown as IShadowEnvElementLegacy).getComponentContext()) || undefined;
});

this.parentEntity$((parent) => this.#onParentEntityChanged(parent));
Expand Down Expand Up @@ -315,7 +315,6 @@ export class ShadowEntityElement extends HTMLElement {
}

#changeNamespace = () => {
this.componentContext = ComponentContext.get(this.ns || GlobalNS);
// TODO a namespace change should trigger a re-connection of all descendants
if (this.isConnected) {
this.#reconnectToShadowTree();
Expand Down
64 changes: 64 additions & 0 deletions packages/shadow-ents/src/elements/ShaeEntElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {createSignal} from '@spearwolf/signalize';
import {GlobalNS} from '../constants.js';
import {ComponentContext, ViewComponent} from '../core.js';
import {generateUUID} from '../generateUUID.js';
import {toNamespace} from '../toNamespace.js';

export class ShaeEntElement extends HTMLElement {
static observedAttributes = ['ns', 'token'];

readonly isShaeElement = true;
readonly isShaeEntElement = true;

readonly uuid = generateUUID();

readonly #namespace = createSignal<string | symbol | undefined>();
readonly #componentContext = createSignal<ComponentContext | undefined>();
readonly #viewComponent = createSignal<ViewComponent | undefined>();

get ns() {
return this.#namespace.value;
}

set ns(ns: string | symbol) {
this.#namespace.set(toNamespace(ns));
}

constructor() {
super();

this.#namespace.onChange((ns) => {
this.#componentContext.set(ComponentContext.get(ns));

if (typeof ns === 'symbol') {
if (this.hasAttribute('ns')) {
this.removeAttribute('ns');
}
} else {
this.setAttribute('ns', ns);
}
});

this.#componentContext.onChange((context) => {
const vc = this.#viewComponent.value;

if (context == null) {
if (vc != null) {
vc.destroy();
}
this.#viewComponent.set(undefined);
return;
}

if (vc == null) {
this.#viewComponent.set(new ViewComponent(this.uuid, {context}));
} else {
vc.context = context;
}
});

this.#namespace.set(GlobalNS);
}

connectedCallback() {}
}
128 changes: 128 additions & 0 deletions packages/shadow-ents/src/elements/ShaeWorkerElement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {createSignal} from '@spearwolf/signalize';
import {GlobalNS} from '../constants.js';
import {toNamespace} from '../toNamespace.js';
import {ComponentContext} from '../view/ComponentContext.js';
import {LocalShadowObjectEnv} from '../view/LocalShadowObjectEnv.js';
import {RemoteWorkerEnv} from '../view/RemoteWorkerEnv.js';
import {ShadowEnv} from '../view/ShadowEnv.js';

const readNamespaceAttribute = (el: HTMLElement) => toNamespace(el.getAttribute('ns'));

const readBooleanAttribute = (el: HTMLElement, name: string) => {
if (el.hasAttribute(name)) {
const val = el.getAttribute(name)?.trim()?.toLowerCase() || 'on';
return ['true', 'on', 'yes', 'local'].includes(val);
}
return false;
};

const AttrNamespace = 'ns';
const AttrLocal = 'local';

export class ShaeWorkerElement extends HTMLElement {
static observedAttributes = [AttrNamespace];

readonly isShaeElement = true;
readonly isShaeWorkerElement = true;

readonly shadowEnv = new ShadowEnv();

readonly #ns = createSignal<string | symbol>(GlobalNS);

#shouldDestroy = false;

constructor() {
super();

this.#ns.onChange((ns) => {
this.shadowEnv.view = ComponentContext.get(ns);
});

this.shadowEnv.on(ShadowEnv.ContextCreated, () => {
this.dispatchEvent(
new CustomEvent(ShadowEnv.ContextCreated.toLowerCase(), {
bubbles: false,
detail: {shadowEnv: this.shadowEnv},
}),
);
});

this.shadowEnv.on(ShadowEnv.ContextLost, () => {
this.dispatchEvent(
new CustomEvent(ShadowEnv.ContextLost.toLowerCase(), {
bubbles: false,
detail: {shadowEnv: this.shadowEnv},
}),
);
});

this.shadowEnv.on(ShadowEnv.AfterSync, () => {
this.dispatchEvent(
new CustomEvent(ShadowEnv.AfterSync.toLowerCase(), {
bubbles: false,
detail: {shadowEnv: this.shadowEnv},
}),
);
});
}

get ns(): string | symbol {
return this.#ns.value;
}

set ns(ns: string | symbol) {
if (typeof ns === 'symbol') {
this.#ns.set(ns);
} else {
this.#ns.set(toNamespace(ns));
}
}

connectedCallback() {
this.start();
}

disconnectedCallback() {
this.#deferDestroy();
}

attributeChangedCallback(name: string) {
if (name === AttrNamespace) {
this.#ns.set(readNamespaceAttribute(this));
}
if (name === AttrLocal) {
if (this.shadowEnv.envProxy != null) {
throw new Error(
'[ShaeWorkerElement] Changing the "local" attribute after the shadowEnv has been created is not supported.',
);
}
}
}

start(): Promise<ShadowEnv> {
this.#shouldDestroy = false;
if (this.shadowEnv.view == null) {
this.shadowEnv.view = ComponentContext.get(this.#ns.value);
}
if (this.shadowEnv.envProxy == null) {
const envProxy = readBooleanAttribute(this, AttrLocal) ? new LocalShadowObjectEnv() : new RemoteWorkerEnv();
this.shadowEnv.envProxy = envProxy;
}
return this.shadowEnv.ready();
}

destroy() {
this.shadowEnv.envProxy = undefined;
}

#deferDestroy() {
if (!this.#shouldDestroy) {
this.#shouldDestroy = true;
queueMicrotask(() => {
if (this.#shouldDestroy) {
this.destroy();
}
});
}
}
}
4 changes: 3 additions & 1 deletion packages/shadow-ents/src/elements/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ export const SHADOW_ELEMENT_ENTITY = 'shadow-entity';
export const SHADOW_ELEMENT_ENV = 'shadow-env';
export const SHADOW_ELEMENT_ENV_LEGACY = 'shadow-env-legacy';
export const SHADOW_ELEMENT_LOCAL_ENV = 'shadow-local-env';

export const SHADOW_ELEMENT_WORKER = 'shadow-worker';

export const SHAE_WORKER = 'shae-worker';
export const SHAE_ENT = 'shae-ent';
2 changes: 2 additions & 0 deletions packages/shadow-ents/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export * from './elements/ShadowEntityElement.js';
export * from './elements/ShadowEnvElement.js';
export * from './elements/ShadowEnvElementLegacy.js';
export * from './elements/ShadowLocalEnvElement.js';
export * from './elements/ShaeEntElement.js';
export * from './elements/ShaeWorkerElement.js';
export * from './elements/constants.js';
export * from './elements/isShadowElement.js';
export * from './entities/Kernel.js';
Expand Down
4 changes: 4 additions & 0 deletions packages/shadow-ents/src/shae-worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {ShaeWorkerElement} from './elements/ShaeWorkerElement.js';
import {SHAE_WORKER} from './elements/constants.js';

customElements.define(SHAE_WORKER, ShaeWorkerElement);
Loading

0 comments on commit 465577c

Please sign in to comment.