Skip to content

Commit

Permalink
refacto(*): the signal is not part of the core anymore
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzofox3 committed Mar 11, 2024
1 parent 941a3a8 commit 4b0bbbf
Show file tree
Hide file tree
Showing 20 changed files with 110 additions and 130 deletions.
21 changes: 13 additions & 8 deletions apps/restaurant-cashier/cart/cart.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@ import { cartEvents, cartService } from './cart.service.js';
export const createCartController =
({ cartService }) =>
(comp) =>
function* ({ $signal, $host, ...rest }) {
function* ({ $host, ...rest }) {
const { render } = $host;
const abortController = new AbortController();
const { signal } = abortController;
$host.render = (args = {}) =>
render({
...args,
...cartService.getState(),
});

cartService.on(cartEvents.CART_CHANGED, () => $host.render(), {
signal: $signal,
signal,
});

yield* comp({
$host,
$signal,
cartService,
...rest,
});
try {
yield* comp({
$host,
cartService,
...rest,
});
} finally {
abortController.abort();
}
};

export const withCartController = createCartController({ cartService });
22 changes: 14 additions & 8 deletions apps/restaurant-cashier/components/ui-alert.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,33 @@ p {
`;

const connectToNotifications = (comp) =>
function* ({ notificationsService, $signal, $host, ...rest }) {
function* ({ notificationsService, $host, ...rest }) {
const controller = new AbortController();
const { signal } = controller;
notificationsService.on(
notificationsEvents.messagePublished,
({ detail }) => {
if (detail.level === 'error') {
$host.render({ notification: detail.payload });
}
},
{ signal: $signal },
{ signal: controller.signal },
);

yield* comp({
$host,
$signal,
...rest,
});
try {
yield* comp({
$host,
signal,
...rest,
});
} finally {
controller.abort();
}
};
export const UIAlert = connectToNotifications(function* ({
$host,
$root,
$signal: signal,
signal,
}) {
const duration = $host.hasAttribute('duration')
? Number($host.getAttribute('duration'))
Expand Down
6 changes: 3 additions & 3 deletions apps/restaurant-cashier/dashboard/dashboard.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { http } from '../utils/http.js';
import { compose } from '../utils/functions.js';

export const withChartData = (comp) => {
return function* ({ $host, $signal, ...rest }) {
http($host.dataset.url, { signal: $signal }).then($host.render);
yield* comp({ $host, $signal, ...rest });
return function* ({ $host, ...rest }) {
http($host.dataset.url).then($host.render);
yield* comp({ $host, ...rest });
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ img[src=''] {
<img aria-hidden="true" alt="" />
`;

export const ImageUploader = function* ({ $host, $root, $signal: signal }) {
export const ImageUploader = function* ({ $host, $root }) {
const abortController = new AbortController();
const { signal } = abortController;
$root.append(template.content.cloneNode(true));
const img = $root.querySelector('img');
const input = $root.querySelector('input');
Expand All @@ -87,13 +89,17 @@ export const ImageUploader = function* ({ $host, $root, $signal: signal }) {
handleFileChange(file);
});

while (true) {
const { attributes } = yield;
const { url = '', status = 'idle' } = attributes;
const label = getLabel({ url, status });
input.disabled = button.disabled = status === 'loading';
button.textContent = label;
img.setAttribute('src', url);
try {
while (true) {
const { attributes } = yield;
const { url = '', status = 'idle' } = attributes;
const label = getLabel({ url, status });
input.disabled = button.disabled = status === 'loading';
button.textContent = label;
img.setAttribute('src', url);
}
} finally {
abortController.abort();
}

async function handleFileChange(file) {
Expand Down
12 changes: 9 additions & 3 deletions apps/restaurant-cashier/products/product-list.controller.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export const createProductListController =
({ productListService }) =>
(comp) =>
function* ({ $signal, $host, ...rest }) {
function* ({ $host, ...rest }) {
const { render } = $host;
const abortController = new AbortController();
const { signal } = abortController;
$host.render = (args = {}) => {
render({
...args,
Expand All @@ -16,9 +18,13 @@ export const createProductListController =
$host.render();
},
{
signal: $signal,
signal,
},
);

yield* comp({ $signal, $host, productListService, ...rest });
try {
yield* comp({ $host, productListService, ...rest });
} finally {
abortController.abort();
}
};
12 changes: 9 additions & 3 deletions apps/restaurant-cashier/router/page-link.component.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { navigationEvents } from './router.js';

export const connectToRouter = (component) =>
function* ({ router, $host, $signal, ...rest }) {
function* ({ router, $host, ...rest }) {
const abortController = new AbortController();
const { signal } = abortController;
const linkHref = $host.getAttribute('href');
router.on(
navigationEvents.ROUTE_CHANGE_SUCCEEDED,
Expand All @@ -10,15 +12,19 @@ export const connectToRouter = (component) =>
const isCurrent = requestedPathname.includes(linkHref);
$host.render({ isCurrent });
},
{ signal: $signal },
{ signal },
);

$host.addEventListener('click', (ev) => {
ev.preventDefault();
router.goTo(linkHref);
});

yield* component({ router, $host, $signal, ...rest });
try {
yield* component({ router, $host, ...rest });
} finally {
abortController.abort();
}
};

export const PageLink = connectToRouter(function* ({ $host }) {
Expand Down
22 changes: 14 additions & 8 deletions apps/restaurant-cashier/router/page-outlet.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ import { navigationEvents } from './router.js';
import { motionSettings } from '../users/preferences.service.js';

const pageOutlet = (component) =>
function* ({ router, $host, $signal, ...rest }) {
function* ({ router, $host, ...rest }) {
const abortController = new AbortController();
const { signal } = abortController;
const render = $host.render.bind($host);
router.on(
navigationEvents.PAGE_LOADED,
({ detail }) => render({ ...detail }),
{ signal: $signal },
{ signal },
);

yield* component({
$host,
$signal,
router,
...rest,
});
try {
yield* component({
$host,
signal,
router,
...rest,
});
} finally {
abortController.abort();
}
};

export const PageOutlet = pageOutlet(function* ({ $host, preferencesService }) {
Expand Down
7 changes: 4 additions & 3 deletions apps/restaurant-cashier/users/preferences.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { preferencesEvents } from './preferences.service.js';
export const createPreferencesController =
({ preferencesService }) =>
(comp) =>
function* ({ $signal, $host, ...rest }) {
function* ({ $host, ...rest }) {
const abortController = new AbortController();
const { signal } = abortController;
const { render } = $host;
$host.render = (args = {}) => {
render({
Expand All @@ -18,12 +20,11 @@ export const createPreferencesController =
$host.render();
},
{
signal: $signal,
signal,
},
);

yield* comp({
$signal,
$host,
preferencesService,
...rest,
Expand Down
11 changes: 7 additions & 4 deletions apps/todomvc/todo-list.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ export const connectTodoService = (
) => {
return injectTodoService(connector);
function* connector({
$signal,
todoService,
$host,
...deps
}: ComponentDependencies<{ todoService: TodoService }>) {
const abortController = new AbortController();
const { render: _render } = $host;

$host.render = (args?) =>
Expand All @@ -26,9 +26,12 @@ export const connectTodoService = (
});

todoService.addEventListener('state-changed', $host.render, {
signal: $signal,
signal: abortController.signal,
});

yield* comp({ $signal, $host, todoService, ...deps });
try {
yield* comp({ $host, todoService, ...deps });
} finally {
abortController.abort();
}
}
};
10 changes: 4 additions & 6 deletions apps/todomvc/views/todo-list.view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { ViewFactory } from '@cofn/view';
export const TodoListView: ViewFactory<
{ todoService: TodoService },
{ state: TodoServiceState }
> = ({ html, todoService, $host, $signal }) => {
> = ({ html, todoService, $host }) => {
bind('todo-toggled', todoService.toggleTodo);
bind('todo-removed', (detail) => {
todoService.removeTodo(detail);
$host.focus();
});
const treeWalker = document.createTreeWalker($host, NodeFilter.SHOW_ELEMENT);
$host.addEventListener('keydown', handleKeydown, { signal: $signal });
$host.addEventListener('focus', handleFocus, { signal: $signal });
$host.addEventListener('keydown', handleKeydown);
$host.addEventListener('focus', handleFocus);

return ({ state }) => {
const { displayedItems = [] } = getModelFromState(state);
Expand All @@ -29,9 +29,7 @@ export const TodoListView: ViewFactory<
};

function bind(eventName, listener) {
$host.addEventListener(eventName, ({ detail }) => listener(detail), {
signal: $signal,
});
$host.addEventListener(eventName, ({ detail }) => listener(detail));
}

function handleKeydown({ key }) {
Expand Down
1 change: 0 additions & 1 deletion packages/controllers/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ test('controller function get passed the routine dependencies along with the sta
}) => {
let hasBeenChecked = false;
const withSimpleController = withController((deps) => {
ok(deps.$signal);
ok(deps.$host);
ok(deps.$root);
ok(deps.state);
Expand Down
4 changes: 0 additions & 4 deletions packages/core/src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export const component = (renderLoop, opts = defaultOptions) => {
const { observedAttributes = [], Klass = HTMLElement, shadow } = opts;
return class extends Klass {
#loop;
#abortController;
#updateStack = [];

static get observedAttributes() {
Expand All @@ -15,13 +14,11 @@ export const component = (renderLoop, opts = defaultOptions) => {

constructor() {
super();
this.#abortController = new AbortController();
const $host = this;
const $root = shadow !== undefined ? $host.attachShadow(shadow) : $host;
this.#loop = renderLoop.bind(this)({
$host,
$root,
$signal: this.#abortController.signal,
});
this.render = this.render.bind(this);
this.#loop.next();
Expand All @@ -35,7 +32,6 @@ export const component = (renderLoop, opts = defaultOptions) => {
// we end the rendering loop only if the component is removed from de DOM. Sometimes it is just moved from one place to another one
window.queueMicrotask(() => {
if (this.isConnected === false) {
this.#abortController.abort();
this.#loop.return();
}
});
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
type ComponentTag = `${string}-${string}`;

export type ComponentDependencies<T = unknown> = T & {
$signal: AbortSignal;
$host: HTMLElement & {
render: <Update extends Record<unknown, unknown>>(input?: Update) => void;
};
Expand Down
Loading

0 comments on commit 4b0bbbf

Please sign in to comment.