Skip to content

Commit

Permalink
fix(react): hydrate react components on append/prepend/before/after
Browse files Browse the repository at this point in the history
  • Loading branch information
tchak committed Jul 10, 2024
1 parent bcf7eb5 commit 9aea8d3
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changeset/moody-turtles-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@coldwired/actions': patch
'@coldwired/react': patch
---

fix some actions
10 changes: 10 additions & 0 deletions packages/actions/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,18 +345,27 @@ export class Actions {
private _after({ targets, fragment }: Pick<MaterializedFragmentAction, 'targets' | 'fragment'>) {
for (const element of targets) {
element.after(getDocumentFragment(fragment, element));
const parent = element.parentElement;
if (parent) {
this.plugins.forEach((plugin) => plugin.onCreateElement?.(parent));
}
}
}

private _before({ targets, fragment }: Pick<MaterializedFragmentAction, 'targets' | 'fragment'>) {
for (const element of targets) {
element.before(getDocumentFragment(fragment, element));
const parent = element.parentElement;
if (parent) {
this.plugins.forEach((plugin) => plugin.onCreateElement?.(parent));
}
}
}

private _append({ targets, fragment }: Pick<MaterializedFragmentAction, 'targets' | 'fragment'>) {
for (const element of targets) {
element.append(getDocumentFragment(fragment, element, true));
this.plugins.forEach((plugin) => plugin.onCreateElement?.(element));
}
}

Expand All @@ -366,6 +375,7 @@ export class Actions {
}: Pick<MaterializedFragmentAction, 'targets' | 'fragment'>) {
for (const element of targets) {
element.prepend(getDocumentFragment(fragment, element, true));
this.plugins.forEach((plugin) => plugin.onCreateElement?.(element));
}
}

Expand Down
74 changes: 74 additions & 0 deletions packages/react/src/actions-react-plugin.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,5 +223,79 @@ describe('@coldwired/react', () => {
);
expect(root.getCache().size).toEqual(1);
});

actions.append({
targets: 'section',
fragment: `<div>toto <${DEFAULT_TAG_NAME}><${REACT_COMPONENT_TAG} ${NAME_ATTRIBUTE}="Counter" ${PROPS_ATTRIBUTE}="${encodeProps({ label: 'One more Count' })}"></${REACT_COMPONENT_TAG}></${DEFAULT_TAG_NAME}></div>`,
});
await actions.ready();
await waitFor(() => {
expect(document.body.innerHTML).toEqual(
layout(
`<section><${DEFAULT_TAG_NAME} id="frag-1"><div><p>My New Count: 3</p><button>Increment</button></div></${DEFAULT_TAG_NAME}><div>toto <${DEFAULT_TAG_NAME}><div><p>One more Count: 0</p><button>Increment</button></div></${DEFAULT_TAG_NAME}></div></section>`,
),
);
expect(root.getCache().size).toEqual(2);
});

actions.update({
targets: 'section',
fragment: '<p>hello</p>',
});
await actions.ready();

actions.prepend({
targets: 'section',
fragment: `<${DEFAULT_TAG_NAME}><${REACT_COMPONENT_TAG} ${NAME_ATTRIBUTE}="Counter" ${PROPS_ATTRIBUTE}="${encodeProps({ label: 'One more Count' })}"></${REACT_COMPONENT_TAG}></${DEFAULT_TAG_NAME}>`,
});
await actions.ready();
await waitFor(() => {
expect(document.body.innerHTML).toEqual(
layout(
`<section><${DEFAULT_TAG_NAME}><div><p>One more Count: 0</p><button>Increment</button></div></${DEFAULT_TAG_NAME}><p>hello</p></section>`,
),
);
expect(root.getCache().size).toEqual(1);
});

actions.update({
targets: 'section',
fragment: '<p>hello</p>',
});
await actions.ready();

actions.after({
targets: 'p',
fragment: `<${DEFAULT_TAG_NAME}><${REACT_COMPONENT_TAG} ${NAME_ATTRIBUTE}="Counter" ${PROPS_ATTRIBUTE}="${encodeProps({ label: 'One more Count' })}"></${REACT_COMPONENT_TAG}></${DEFAULT_TAG_NAME}>`,
});
await actions.ready();
await waitFor(() => {
expect(document.body.innerHTML).toEqual(
layout(
`<section><p>hello</p><${DEFAULT_TAG_NAME}><div><p>One more Count: 0</p><button>Increment</button></div></${DEFAULT_TAG_NAME}></section>`,
),
);
expect(root.getCache().size).toEqual(1);
});

actions.update({
targets: 'section',
fragment: '<p>hello</p>',
});
await actions.ready();

actions.before({
targets: 'p',
fragment: `<${DEFAULT_TAG_NAME}><${REACT_COMPONENT_TAG} ${NAME_ATTRIBUTE}="Counter" ${PROPS_ATTRIBUTE}="${encodeProps({ label: 'One more Count' })}"></${REACT_COMPONENT_TAG}></${DEFAULT_TAG_NAME}>`,
});
await actions.ready();
await waitFor(() => {
expect(document.body.innerHTML).toEqual(
layout(
`<section><${DEFAULT_TAG_NAME}><div><p>One more Count: 0</p><button>Increment</button></div></${DEFAULT_TAG_NAME}><p>hello</p></section>`,
),
);
expect(root.getCache().size).toEqual(1);
});
});
});
7 changes: 6 additions & 1 deletion packages/react/src/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ export function createRoot(

const notify = () => {
if (!isDestroyed) {
cache.forEach((_, element) => {
if (!element.isConnected) {
cache.delete(element);
mounted.delete(element);
}
});
cache = new Map(cache);
subscriptions.forEach((callback) => callback());
}
Expand All @@ -107,7 +113,6 @@ export function createRoot(
if (isElement(fragment) && fragment.tagName.toLowerCase() != schema.fragmentTagName) {
throw new Error('Cannot rerender with a non-fragment element');
}
//const { hydrate } = await import('./react-tree-builder');
await preload(fragment, (names) => manifestLoader(names, loader, manifest), schema);
const tree = hydrate(fragment, manifest, schema);
if (reset) {
Expand Down
2 changes: 1 addition & 1 deletion turbo.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
Expand Down

0 comments on commit 9aea8d3

Please sign in to comment.