Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add props to TramOneElements for devtools #198

Merged
merged 4 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tram-one",
"version": "13.2.0",
"version": "13.2.1",
"description": "🚋 Modern View Framework for Vanilla Javascript",
"main": "dist/tram-one.cjs",
"commonjs": "dist/tram-one.cjs",
Expand Down
16 changes: 15 additions & 1 deletion src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ import {
} from './working-key';
import observeTag from './observe-tag';
import processHooks from './process-hooks';
import { TRAM_TAG, TRAM_TAG_NEW_EFFECTS, TRAM_TAG_CLEANUP_EFFECTS } from './node-names';
import {
TRAM_TAG,
TRAM_TAG_NEW_EFFECTS,
TRAM_TAG_CLEANUP_EFFECTS,
TRAM_TAG_NAME,
TRAM_TAG_PROPS,
TRAM_TAG_CHILDREN,
} from './node-names';

import { Registry, Props, DOMTaggedTemplateFunction, Children, TramOneHTMLElement, TramOneSVGElement } from './types';

Expand Down Expand Up @@ -69,6 +76,13 @@ export const registerDom = <ElementType extends TramOneHTMLElement | TramOneSVGE
// cleanup effects will be populated when new effects are processed
tagResult[TRAM_TAG_CLEANUP_EFFECTS] = [];

// save properties for development debugging
if (process.env.NODE_ENV === 'development') {
tagResult[TRAM_TAG_NAME] = tagName;
tagResult[TRAM_TAG_PROPS] = props;
tagResult[TRAM_TAG_CHILDREN] = children;
}
Comment on lines +80 to +84
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these properties are not otherwise on the tag, so we need to add them (but only for development).

tagName here is based on what the parent component used to add this to the registry.


return tagResult;
};

Expand Down
1 change: 1 addition & 0 deletions src/engine-names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export const TRAM_EFFECT_STORE = 'tram-effect-store';
export const TRAM_EFFECT_QUEUE = 'tram-effect-queue';
export const TRAM_KEY_STORE = 'tram-key-store';
export const TRAM_KEY_QUEUE = 'tram-key-queue';
export const TRAM_GLOBAL_KEY_QUEUE = 'tram-global-key-queue';
export const TRAM_OBSERVABLE_STORE = 'tram-observable-store';
export const TRAM_MUTATION_OBSERVER = 'tram-mutation-observer';
6 changes: 6 additions & 0 deletions src/node-names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ export const TRAM_TAG_REACTION = 'tram-tag-reaction';
export const TRAM_TAG_STORE_KEYS = 'tram-tag-store-keys';
export const TRAM_TAG_NEW_EFFECTS = 'tram-tag-new-effects';
export const TRAM_TAG_CLEANUP_EFFECTS = 'tram-tag-cleanup-effects';

// Debug properties used for tram-one dev tools
export const TRAM_TAG_NAME = 'tram-tag-name';
export const TRAM_TAG_PROPS = 'tram-tag-props';
export const TRAM_TAG_CHILDREN = 'tram-tag-children';
export const TRAM_TAG_GLOBAL_STORE_KEYS = 'tram-tag-global-store-keys';
7 changes: 6 additions & 1 deletion src/observable-hook.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TRAM_OBSERVABLE_STORE, TRAM_HOOK_KEY, TRAM_KEY_QUEUE } from './engine-names';
import { TRAM_OBSERVABLE_STORE, TRAM_HOOK_KEY, TRAM_KEY_QUEUE, TRAM_GLOBAL_KEY_QUEUE } from './engine-names';
import { getObservableStore } from './observable-store';
import { getWorkingKeyValue, incrementWorkingKeyBranch } from './working-key';

Expand Down Expand Up @@ -40,6 +40,11 @@ export default <Store extends StoreObject>(key?: string, value?: Store): Store =
getKeyQueue(TRAM_KEY_QUEUE).push(resolvedKey);
}

// if this is a development environment, save the global store key to the element
if (!isLocalStore && process.env.NODE_ENV === 'development') {
getKeyQueue(TRAM_GLOBAL_KEY_QUEUE).push(resolvedKey);
}

// return value
return keyValue;
};
24 changes: 23 additions & 1 deletion src/observe-tag.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
const { observe } = require('@nx-js/observer-util');

import { TRAM_TAG_REACTION, TRAM_TAG_NEW_EFFECTS, TRAM_TAG_CLEANUP_EFFECTS, TRAM_TAG } from './node-names';
import {
TRAM_TAG_REACTION,
TRAM_TAG_NEW_EFFECTS,
TRAM_TAG_CLEANUP_EFFECTS,
TRAM_TAG,
TRAM_TAG_NAME,
TRAM_TAG_PROPS,
TRAM_TAG_GLOBAL_STORE_KEYS,
} from './node-names';
import { TramOneElement, RemovedElementDataStore, Reaction, ElementPotentiallyWithSelectionAndFocus } from './types';

// functions to go to nodes or indices (made for .map)
Expand Down Expand Up @@ -97,6 +105,13 @@ export default (tagFunction: () => TramOneElement): TramOneElement => {
emptyDiv[TRAM_TAG_NEW_EFFECTS] = oldTag[TRAM_TAG_NEW_EFFECTS];
emptyDiv[TRAM_TAG_CLEANUP_EFFECTS] = oldTag[TRAM_TAG_CLEANUP_EFFECTS];

// copy over development props
if (process.env.NODE_ENV === 'development') {
emptyDiv[TRAM_TAG_NAME] = oldTag[TRAM_TAG_NAME];
emptyDiv[TRAM_TAG_PROPS] = oldTag[TRAM_TAG_PROPS];
emptyDiv[TRAM_TAG_GLOBAL_STORE_KEYS] = oldTag[TRAM_TAG_GLOBAL_STORE_KEYS];
}

// set oldTag to emptyDiv, so we can replace it later
oldTag = emptyDiv;
}
Expand Down Expand Up @@ -146,6 +161,13 @@ export default (tagFunction: () => TramOneElement): TramOneElement => {
tagResult[TRAM_TAG_NEW_EFFECTS] = oldTag[TRAM_TAG_NEW_EFFECTS];
tagResult[TRAM_TAG_CLEANUP_EFFECTS] = oldTag[TRAM_TAG_CLEANUP_EFFECTS];

// copy over development props
if (process.env.NODE_ENV === 'development') {
tagResult[TRAM_TAG_NAME] = oldTag[TRAM_TAG_NAME];
tagResult[TRAM_TAG_PROPS] = oldTag[TRAM_TAG_PROPS];
tagResult[TRAM_TAG_GLOBAL_STORE_KEYS] = oldTag[TRAM_TAG_GLOBAL_STORE_KEYS];
}

// both these actions cause forced reflow, and can be performance issues
oldTag.replaceWith(tagResult);
if (elementToGiveFocus && elementToGiveFocus.focus) elementToGiveFocus.focus();
Expand Down
15 changes: 13 additions & 2 deletions src/process-hooks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TRAM_EFFECT_STORE, TRAM_EFFECT_QUEUE, TRAM_KEY_QUEUE } from './engine-names';
import { TRAM_TAG_NEW_EFFECTS, TRAM_TAG_STORE_KEYS } from './node-names';
import { TRAM_EFFECT_STORE, TRAM_EFFECT_QUEUE, TRAM_KEY_QUEUE, TRAM_GLOBAL_KEY_QUEUE } from './engine-names';
import { TRAM_TAG_GLOBAL_STORE_KEYS, TRAM_TAG_NEW_EFFECTS, TRAM_TAG_STORE_KEYS } from './node-names';
import { getEffectStore, clearEffectStore, restoreEffectStore } from './effect-store';
import { TramOneElement } from './types';
import { clearKeyQueue, getKeyQueue, restoreKeyQueue } from './key-queue';
Expand All @@ -20,6 +20,7 @@ export default (tagFunction: () => TramOneElement) => {
// clear the queues (so we can get just new effects and keys)
clearEffectStore(TRAM_EFFECT_QUEUE);
clearKeyQueue(TRAM_KEY_QUEUE);
clearKeyQueue(TRAM_GLOBAL_KEY_QUEUE);

// create the component, which will save new effects to the effect queue
const tagResult = tagFunction();
Expand Down Expand Up @@ -48,6 +49,16 @@ export default (tagFunction: () => TramOneElement) => {
const existingNewAndBrandNewKeys = existingNewKeys.concat(newKeys);
tagResult[TRAM_TAG_STORE_KEYS] = existingNewAndBrandNewKeys;

// if this is development environment, save global store keys to the element
if (process.env.NODE_ENV === 'development') {
const existingNewGlobalKeys = tagResult[TRAM_TAG_GLOBAL_STORE_KEYS] || [];
const newGlobalKeys = getKeyQueue(TRAM_GLOBAL_KEY_QUEUE);

// store global store keys in the node we just built
const existingNewAndBrandNewGlobalKeys = existingNewGlobalKeys.concat(newGlobalKeys);
tagResult[TRAM_TAG_GLOBAL_STORE_KEYS] = existingNewAndBrandNewGlobalKeys;
}
Comment on lines +52 to +60
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mostly a copy-paste of how we handle local stores, so the logic isn't super novel here.

This will hopefully be simplified (or not required) when #189 is completed.


// restore the effect and key queues to what they were before we started
restoreEffectStore(TRAM_EFFECT_QUEUE, existingQueuedEffects);
restoreKeyQueue(TRAM_KEY_QUEUE, existingQueuedKeys);
Expand Down
4 changes: 4 additions & 0 deletions src/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TRAM_MUTATION_OBSERVER,
TRAM_KEY_QUEUE,
TRAM_KEY_STORE,
TRAM_GLOBAL_KEY_QUEUE,
} from './engine-names';
import { setupTramOneSpace } from './namespace';
import { setupEffectStore } from './effect-store';
Expand Down Expand Up @@ -59,6 +60,9 @@ export default (component: RootTramOneComponent, target: ElementOrSelector) => {
// setup key queue for new observable stores when resolving mounts
setupKeyQueue(TRAM_KEY_QUEUE);

// setup key queue for global observable stores when resolving mounts
setupKeyQueue(TRAM_GLOBAL_KEY_QUEUE);
Comment on lines +63 to +64
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a huge fan of setting up a whole new key queue here, but there really isn't a better way to associate hooks used in the render with their elements.


// setup a mutation observer for cleaning up removed elements and triggering effects
setupMutationObserver(TRAM_MUTATION_OBSERVER);

Expand Down
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import {
TRAM_TAG_NEW_EFFECTS,
TRAM_TAG_CLEANUP_EFFECTS,
TRAM_TAG_STORE_KEYS,
TRAM_TAG_NAME,
TRAM_TAG_PROPS,
TRAM_TAG_GLOBAL_STORE_KEYS,
TRAM_TAG_CHILDREN,
} from './node-names';

/* ============= PUBLIC TYPES ========================================
Expand Down Expand Up @@ -106,6 +110,12 @@ export interface TramOneElement extends Element {
[TRAM_TAG_NEW_EFFECTS]: Effect[];
[TRAM_TAG_CLEANUP_EFFECTS]: CleanupEffect[];
[TRAM_TAG_STORE_KEYS]: string[];

// development properties, these are not guarnteed to be on the element
[TRAM_TAG_NAME]?: string;
[TRAM_TAG_PROPS]?: Props;
[TRAM_TAG_CHILDREN]?: Children;
[TRAM_TAG_GLOBAL_STORE_KEYS]?: string[];
Comment on lines +114 to +118
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even if the app is running in development mode, some properties (like props or children) could be undefined.

}

export type TramOneHTMLElement = TramOneElement & HTMLElement;
Expand Down