Skip to content

Commit

Permalink
[experiment] simplify updating opcodes (#121)
Browse files Browse the repository at this point in the history
* simplify reactivity

* +

* +

* +
  • Loading branch information
lifeart authored May 4, 2024
1 parent 77a8644 commit e636e26
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 87 deletions.
2 changes: 1 addition & 1 deletion src/tests/integration/let-test.gts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ module('Integration | InternalComponent | let', function () {
</template>;
const time = cell(Date.now(), 'time');
function updateTime() {
time.update(Date.now());
time.update(Date.now() + 124);
}
await render(<template><Display @value={{time}} /></template>);
assert.dom('[data-test-1]').hasText(`hello world!${time.value}`);
Expand Down
2 changes: 1 addition & 1 deletion src/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export async function render(component: ComponentReturnType) {
return renderResult;
}

export async function rerender(timeout = 0) {
export async function rerender(timeout = 16) {
return new Promise((resolve) => {
setTimeout(resolve, timeout);
});
Expand Down
129 changes: 46 additions & 83 deletions src/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,10 @@ let unstableWrapperId: number = 0;
let ROOT: Component<any> | null = null;

export function $_TO_VALUE(reference: unknown) {
if (isPrimitive(reference)) {
return reference;
} else if (isTagLike(reference)) {
return reference;
} else {
if (isFn(reference)) {
return resolveRenderable(reference as Function);
} else {
return reference;
}
}

Expand Down Expand Up @@ -166,34 +164,25 @@ function $prop(
value: unknown,
destructors: DestructorFn[],
) {
if (isPrimitive(value)) {
api.prop(element, key, value);
} else if (isFn(value)) {
$prop(
element,
key,
resolveRenderable(value, `${element.tagName}.${key}`),
destructors,
);
} else if (value !== null && isTagLike(value)) {
const result = $_TO_VALUE(value);
if (isEmpty(result)) {
return;
}
if (isPrimitive(result)) {
if (isRehydrationScheduled()) {
return;
}
api.prop(element, key, result);
} else {
let prevPropValue: any = undefined;
destructors.push(
opcodeFor(value as AnyCell, (value) => {
opcodeFor(result as AnyCell, (value) => {
if (value === prevPropValue) {
return;
}
prevPropValue = api.prop(element, key, value);
}),
);
} else {
if (isRehydrationScheduled()) {
// we should have all static keys settled
return;
} else {
if (IS_DEV_MODE) {
throw new Error(`Unknown value ${typeof value} for property ${key}`);
}
}
}
}

Expand All @@ -203,27 +192,19 @@ function $attr(
value: unknown,
destructors: Destructors,
) {
if (isPrimitive(value)) {
// @ts-expect-error type casting
api.attr(element, key, value);
} else if (isFn(value)) {
$attr(
element,
key,
resolveRenderable(value, `${element.tagName}.${key}`),
destructors,
);
} else if (value !== null && isTagLike(value)) {
const result = $_TO_VALUE(value);
if (isEmpty(result)) {
return;
}
if (isPrimitive(result)) {
api.attr(element, key, result as string);
} else {
destructors.push(
opcodeFor(value as AnyCell, (value) => {
opcodeFor(result as AnyCell, (value) => {
// @ts-expect-error type casting
api.attr(element, key, value);
}),
);
} else {
if (IS_DEV_MODE) {
throw new Error(`Unknown value ${typeof value} for attribute ${key}`);
}
}
}

Expand All @@ -240,7 +221,7 @@ function resolveRenderable(
f.destroy();
return componentProps;
} else {
if (isPrimitive(componentProps)) {
if (isPrimitive(componentProps) || isEmpty(componentProps)) {
return f;
} else {
// looks like a component
Expand Down Expand Up @@ -293,34 +274,18 @@ function $ev(
) {
// textContent is a special case
if (eventName === EVENT_TYPE.TEXT_CONTENT) {
if (isFn(fn)) {
const value = resolveRenderable(fn, `${element.tagName}.textContent`);
if (isPrimitive(value)) {
api.textContent(element, String(value));
} else if (isTagLike(value)) {
destructors.push(
opcodeFor(value, (value) => {
api.textContent(element, String(value));
}),
);
} else {
return value; // objet
// throw new Error('invalid textContent value');
}
const result = $_TO_VALUE(fn);
if (isEmpty(result)) {
return;
}
if (isPrimitive(result)) {
api.textContent(element, result as string);
} else {
if (IS_GLIMMER_COMPAT_MODE) {
api.textContent(element, fn);
} else {
if (isPrimitive(fn)) {
api.textContent(element, String(fn));
} else if (isTagLike(fn)) {
destructors.push(
opcodeFor(fn, (value) => {
api.textContent(element, String(value));
}),
);
}
}
destructors.push(
opcodeFor(result as AnyCell, (value) => {
api.textContent(element, String(value));
}),
);
}
// modifier case
} else if (eventName === EVENT_TYPE.ON_CREATED) {
Expand Down Expand Up @@ -723,7 +688,7 @@ function _component(
}
// @ts-expect-error construct signature
let instance = comp.prototype === undefined ? comp(args, fw) : new (comp as unknown as Component<any>)(args, fw);
if (typeof instance === 'function') {
if (isFn(instance)) {
instance = new instance(args, fw);
}
// todo - fix typings here
Expand Down Expand Up @@ -789,6 +754,9 @@ function mergeComponents(
if (isFn(component)) {
component = text(resolveRenderable(component, 'merge-components'), $destructors);
}
if (isEmpty(component)) {
return;
}
if (isPrimitive(component)) {
nodes.push(api.text(component));
} else if ($nodes in component) {
Expand Down Expand Up @@ -890,20 +858,15 @@ function text(
text: string | number | null | Cell | MergedCell | Fn | RenderableType,
destructors: Destructors,
): Text {
if (isPrimitive(text)) {
return api.text(text);
} else if (text !== null && isTagLike(text)) {
return cellToText(text as AnyCell, destructors);
} else if (isFn(text)) {
// @ts-expect-error return type
return text(resolveRenderable(fn, `fnToText`), destructors);
}
if (typeof text === 'object') {
// TODO: change fn name?
return text as Text;
const result = $_TO_VALUE(text);
if (isEmpty(result)) {
return api.text('');
} else if (isPrimitive(result)) {
return api.text(result);
} else {
// @ts-expect-error
return cellToText(typeof text === 'function' ? result : text, destructors);
}

return api.text('');
}

function ifCond(
Expand Down
3 changes: 1 addition & 2 deletions src/utils/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ export function isPrimitive(value: unknown): value is string | number {
vType === 'string' ||
vType === 'number' ||
vType === 'boolean' ||
vType === 'bigint' ||
vType === 'undefined'
vType === 'bigint'
);
}

Expand Down

0 comments on commit e636e26

Please sign in to comment.