@api-client/ui 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"Application.js","sourceRoot":"","sources":["../../../src/core/Application.ts"],"names":[],"mappings":"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","sourcesContent":["import { nothing, type TemplateResult } from 'lit'\nimport { ActivityManager, ActivityState } from './ActivityManager.js'\nimport type { Activity } from './Activity.js'\nimport { ApplicationRenderer } from './renderer/ApplicationRenderer.js'\nimport { ThemeManager } from './ThemeManager.js'\n\n/**\n * Allows to fine-tune the update request.\n * For example, if a `Fragment` wants to update only itself, then\n * list other types should be set to false.\n */\nexport interface UpdateRequest {\n /**\n * Whether the whole application should be updated.\n * Default to true.\n */\n app?: boolean\n /**\n * Whether the activity should be updated.\n * Default to true.\n */\n activity?: boolean\n /**\n * Whether the fragment should be updated.\n * Default to true.\n */\n fragment?: boolean\n}\n/**\n * The application represents an application screen that hosts\n * Activities. Activities are managed by the Activity manager.\n *\n * An application is a separate app within the ecosystem. For example,\n * the file browser is one application. The domain designer is another.\n *\n * Each application manages it's own lifecycle. The application is rendered\n * by the lit's library `render()` function. Activities can call application's\n * main `requestUpdate()` function to render the entire application.\n *\n * Activities have the render function that renders its UI.\n * The Activity's UI can be composed of fragments, but this is optional.\n * When an activity uses fragments, they receive control over rendering their\n * UIs. An activity implementation has to take care of passing HTMLElement\n * references to their Fragments to make that happen. Otherwise, the activity\n * has to communicate with their fragments to request to re-render the application.\n */\nexport abstract class Application extends EventTarget {\n private activityUpdateListener = this.handleActivityUpdate.bind(this)\n\n #activities: ActivityManager\n\n #theme: ThemeManager\n\n /**\n * Application's theme manager.\n */\n get theme(): ThemeManager {\n return this.#theme\n }\n\n /**\n * Returns the application's activity manager.\n */\n get manager(): ActivityManager {\n return this.#activities\n }\n\n #events: EventTarget\n\n /**\n * The application main event bus.\n * All activities and fragments use it to communicate.\n * This way, events do not leak outside the application.\n */\n get events(): EventTarget {\n return this.#events\n }\n\n #renderer: ApplicationRenderer\n\n get renderer(): ApplicationRenderer {\n return this.#renderer\n }\n\n /**\n * @type A promise resolved when the render finished.\n */\n get updateComplete(): Promise<void> | undefined {\n return this.#renderer.updateComplete\n }\n\n /**\n * @type True when the application was first rendered.\n */\n get firstRendered(): boolean {\n return this.#renderer.firstRendered\n }\n\n /**\n * @param renderRoot The element or a CSS query to the element where the application will be rendered.\n */\n constructor(renderRoot: HTMLElement | string) {\n super()\n this.#events = new EventTarget()\n this.#activities = new ActivityManager(this)\n this.#renderer = new ApplicationRenderer(this)\n this.#renderer.setRenderRoot(renderRoot)\n this.#theme = new ThemeManager()\n\n // Listen for activity updates\n this.#events.addEventListener('activity:update', this.activityUpdateListener as EventListener)\n }\n\n /**\n * @see {@link ./Renderer.js}\n */\n public setRenderRoot(renderRoot: HTMLElement | string): void {\n this.#renderer.setRenderRoot(renderRoot)\n }\n\n /**\n * Called when the application starts.\n * This is where you should start the initial Activity using\n * `ActivityManager.startActivity(...)`.\n */\n abstract onStart(): void | Promise<void>\n\n /**\n * Called when the application is stopped/closed.\n * Perform cleanup here.\n */\n onStop(): void | Promise<void> {\n //\n }\n\n /**\n * Called when the application was rendered for the first time.\n * Call `super.onFirstRender()` when overriding this method.\n */\n onFirstRender(): void {\n this.#events.dispatchEvent(new Event('app:first-render'))\n }\n\n /**\n * Called when the application was rendered.\n */\n onRendered(): void {\n //\n }\n\n /**\n * The main render method for the Application. Called whenever an activity\n * requests an update. Renders the currently active Activity's content.\n *\n * If you override this method then any activity won't be rendered.\n *\n * @returns The Lit template to render.\n */\n render(): TemplateResult | typeof nothing {\n const currentActivity = this.#activities.getCurrentActivity()\n // Only render if started or beyond\n if (currentActivity && currentActivity.state >= ActivityState.Started) {\n return currentActivity.render()\n }\n return nothing\n }\n\n /**\n * Handles activity update requests and re-renders the application.\n */\n private handleActivityUpdate(e: CustomEvent<UpdateRequest | undefined>): void {\n this.requestUpdate(e.detail || undefined)\n }\n\n /**\n * Requests an update of the application UI. This will call the `render()` method\n * and update the DOM.\n */\n requestUpdate(opts: UpdateRequest = {}): void {\n const { app = true } = opts\n if (app) {\n this.#renderer.requestUpdate()\n }\n }\n\n /**\n * Starts the application by calling onStart and performing an initial render.\n */\n public async run(): Promise<void> {\n await this.onStart()\n this.requestUpdate()\n }\n\n /**\n * Stops the application, performing cleanup if necessary.\n */\n public async stop(): Promise<void> {\n this.#events.removeEventListener('activity:update', this.activityUpdateListener as EventListener)\n // Allow subclasses to clean up\n await this.onStop()\n // ... any other application-level cleanup\n }\n\n getCurrentActivity(): Activity | undefined {\n return this.#activities.getCurrentActivity()\n }\n\n /**\n * Unifies Fragment and Application interfaces.\n * @returns `this`\n */\n getApplication() {\n return this\n }\n\n findActiveActivity(id: string): Activity | undefined {\n return this.#activities.findActiveActivity(id)\n }\n}\n"]}
1
+ {"version":3,"file":"Application.js","sourceRoot":"","sources":["../../../src/core/Application.ts"],"names":[],"mappings":"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","sourcesContent":["import { nothing, type TemplateResult } from 'lit'\nimport { ActivityManager, ActivityLifecycle } from './ActivityManager.js'\nimport type { Activity } from './Activity.js'\nimport { ApplicationRenderer } from './renderer/ApplicationRenderer.js'\nimport { ThemeManager } from './ThemeManager.js'\n\n/**\n * Allows to fine-tune the update request.\n * For example, if a `Fragment` wants to update only itself, then\n * list other types should be set to false.\n */\nexport interface UpdateRequest {\n /**\n * Whether the whole application should be updated.\n * Default to true.\n */\n app?: boolean\n /**\n * Whether the activity should be updated.\n * Default to true.\n */\n activity?: boolean\n /**\n * Whether the fragment should be updated.\n * Default to true.\n */\n fragment?: boolean\n}\n/**\n * The application represents an application screen that hosts\n * Activities. Activities are managed by the Activity manager.\n *\n * An application is a separate app within the ecosystem. For example,\n * the file browser is one application. The domain designer is another.\n *\n * Each application manages it's own lifecycle. The application is rendered\n * by the lit's library `render()` function. Activities can call application's\n * main `requestUpdate()` function to render the entire application.\n *\n * Activities have the render function that renders its UI.\n * The Activity's UI can be composed of fragments, but this is optional.\n * When an activity uses fragments, they receive control over rendering their\n * UIs. An activity implementation has to take care of passing HTMLElement\n * references to their Fragments to make that happen. Otherwise, the activity\n * has to communicate with their fragments to request to re-render the application.\n */\nexport abstract class Application extends EventTarget {\n private activityUpdateListener = this.handleActivityUpdate.bind(this)\n\n #activities: ActivityManager\n\n #theme: ThemeManager\n\n /**\n * Application's theme manager.\n */\n get theme(): ThemeManager {\n return this.#theme\n }\n\n /**\n * Returns the application's activity manager.\n */\n get manager(): ActivityManager {\n return this.#activities\n }\n\n #events: EventTarget\n\n /**\n * The application main event bus.\n * All activities and fragments use it to communicate.\n * This way, events do not leak outside the application.\n */\n get events(): EventTarget {\n return this.#events\n }\n\n #renderer: ApplicationRenderer\n\n get renderer(): ApplicationRenderer {\n return this.#renderer\n }\n\n /**\n * @type A promise resolved when the render finished.\n */\n get updateComplete(): Promise<void> | undefined {\n return this.#renderer.updateComplete\n }\n\n /**\n * @type True when the application was first rendered.\n */\n get firstRendered(): boolean {\n return this.#renderer.firstRendered\n }\n\n /**\n * @param renderRoot The element or a CSS query to the element where the application will be rendered.\n */\n constructor(renderRoot: HTMLElement | string) {\n super()\n this.#events = new EventTarget()\n this.#activities = new ActivityManager(this)\n this.#renderer = new ApplicationRenderer(this)\n this.#renderer.setRenderRoot(renderRoot)\n this.#theme = new ThemeManager()\n\n // Listen for activity updates\n this.#events.addEventListener('activity:update', this.activityUpdateListener as EventListener)\n }\n\n /**\n * @see {@link ./Renderer.js}\n */\n public setRenderRoot(renderRoot: HTMLElement | string): void {\n this.#renderer.setRenderRoot(renderRoot)\n }\n\n /**\n * Called when the application starts.\n * This is where you should start the initial Activity using\n * `ActivityManager.startActivity(...)`.\n */\n abstract onStart(): void | Promise<void>\n\n /**\n * Called when the application is stopped/closed.\n * Perform cleanup here.\n */\n onStop(): void | Promise<void> {\n //\n }\n\n /**\n * Called when the application was rendered for the first time.\n * Call `super.onFirstRender()` when overriding this method.\n */\n onFirstRender(): void {\n this.#events.dispatchEvent(new Event('app:first-render'))\n }\n\n /**\n * Called when the application was rendered.\n */\n onRendered(): void {\n //\n }\n\n /**\n * The main render method for the Application. Called whenever an activity\n * requests an update. Renders the currently active Activity's content.\n *\n * If you override this method then any activity won't be rendered.\n *\n * @returns The Lit template to render.\n */\n render(): TemplateResult | typeof nothing {\n const currentActivity = this.#activities.getCurrentActivity()\n // Only render if started or beyond\n if (currentActivity && currentActivity.lifecycle >= ActivityLifecycle.Started) {\n return currentActivity.render()\n }\n return nothing\n }\n\n /**\n * Handles activity update requests and re-renders the application.\n */\n private handleActivityUpdate(e: CustomEvent<UpdateRequest | undefined>): void {\n this.requestUpdate(e.detail || undefined)\n }\n\n /**\n * Requests an update of the application UI. This will call the `render()` method\n * and update the DOM.\n */\n requestUpdate(opts: UpdateRequest = {}): void {\n const { app = true } = opts\n if (app) {\n this.#renderer.requestUpdate()\n }\n }\n\n /**\n * Starts the application by calling onStart and performing an initial render.\n */\n public async run(): Promise<void> {\n await this.onStart()\n this.requestUpdate()\n }\n\n /**\n * Stops the application, performing cleanup if necessary.\n */\n public async stop(): Promise<void> {\n this.#events.removeEventListener('activity:update', this.activityUpdateListener as EventListener)\n // Allow subclasses to clean up\n await this.onStop()\n // ... any other application-level cleanup\n }\n\n getCurrentActivity(): Activity | undefined {\n return this.#activities.getCurrentActivity()\n }\n\n /**\n * Unifies Fragment and Application interfaces.\n * @returns `this`\n */\n getApplication() {\n return this\n }\n\n findActiveActivity(id: string): Activity | undefined {\n return this.#activities.findActiveActivity(id)\n }\n}\n"]}
@@ -49,7 +49,7 @@ let ModalActivity = (() => {
49
49
  formId = __runInitializers(this, _opened_extraInitializers);
50
50
  onResume() {
51
51
  this.renderRoot = document.createElement('div');
52
- this.renderRoot.classList.add('modal-activit-container');
52
+ this.renderRoot.classList.add('modal-activity-container');
53
53
  document.body.appendChild(this.renderRoot);
54
54
  super.onResume();
55
55
  this.requestUpdate();
@@ -1 +1 @@
1
- {"version":3,"file":"ModalActivity.js","sourceRoot":"","sources":["../../../src/core/ModalActivity.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, type TemplateResult } from 'lit'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { Activity } from './Activity.js'\nimport type { UiDialogClosingReason } from '../md/dialog/internals/Dialog.js'\nimport state from '../decorators/state.js'\nimport { IntentResult } from './ActivityManager.js'\n\nimport '../md/dialog/ui-dialog.js'\nimport '../md/button/ui-text-button.js'\n\nexport interface ActionButtonInit {\n /**\n * The label to use for the button.\n */\n label?: string\n /**\n * Whether the button is disabled.\n */\n disabled?: boolean\n}\n\n/**\n * A special kind of activity that renders content in a modal dialog.\n * When a modal activity is running the underlying activities are paused.\n *\n * A modal activity uses the UiDialogElement to render its content. The dialog\n * is inserted directly into the `<body>` element of the document and rendered\n * in the top layer. Because of that, the modal activity does not support\n * regular rendering logic. It creates its own render root that is used to render\n * the template.\n */\nexport abstract class ModalActivity extends Activity {\n /**\n * The list of classes to apply to the dialog.\n */\n protected dialogClasses: Record<string, boolean> = {}\n /**\n * Controls dialog visibility without controlling the activity state.\n */\n @state() accessor opened = true\n\n /**\n * The id of the form used to render the dialog.\n */\n protected formId?: string\n\n override onResume(): void | Promise<void> {\n this.renderRoot = document.createElement('div')\n this.renderRoot.classList.add('modal-activit-container')\n document.body.appendChild(this.renderRoot)\n super.onResume()\n this.requestUpdate()\n }\n\n override async finish(): Promise<void> {\n if (this.renderRoot) {\n document.body.removeChild(this.renderRoot)\n this.renderRoot = undefined\n }\n await super.finish()\n }\n\n protected handleDialogClosed(e: CustomEvent<UiDialogClosingReason>): void {\n const { cancelled, value } = e.detail\n if (cancelled) {\n this.handleNegativeAction(value)\n } else {\n this.handlePositiveAction(value)\n }\n }\n\n /**\n * Called when the dialog is closed with a negative action.\n * Override this function to handle the negative action.\n * @param value The value passed to the dialog when it is closed.\n */\n protected handleNegativeAction(value: unknown): void {\n this.setResult(IntentResult.RESULT_CANCELED, value)\n this.finish()\n }\n\n /**\n * Called when the dialog is closed with a positive action.\n * Override this function to handle the positive action.\n * @param value The value passed to the dialog when it is closed.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected handlePositiveAction(value: unknown): void {\n this.finish()\n }\n\n /**\n * Override this method to handle the form submission.\n * @param e The submit event.\n */\n protected handleSubmit(e: SubmitEvent): void {\n e.preventDefault()\n }\n\n /**\n * The function called by the rendered when rendering this dialog.\n * This way, the `render()` function is still used as the primary template provider.\n */\n renderDialog(): TemplateResult {\n const classes = {\n activityDialog: true,\n [this.constructor.name.toLowerCase()]: true,\n ...this.dialogClasses,\n }\n return html`<ui-dialog modal .open=\"${this.opened}\" class=\"${classMap(classes)}\" @close=\"${this.handleDialogClosed}\"\n >${this.render()}</ui-dialog\n >`\n }\n\n /**\n * Used with dialogs that render forms. Override the `handleSubmit` method\n * to handle the form submission.\n * @param content The content to render in the form.\n * @param name Optional form name\n */\n protected renderForm(content: TemplateResult, name?: string): TemplateResult {\n if (!this.formId) {\n this.formId = `form-${this.constructor.name.toLowerCase()}`\n }\n return html`<form\n id=\"${this.formId}\"\n name=\"${ifDefined(name)}\"\n class=\"dialog-content\"\n @submit=\"${this.handleSubmit}\"\n >\n ${content}\n </form>`\n }\n\n /**\n * Renders the cancel button for the dialog.\n * @param label The label to use for the cancel button.\n */\n protected renderNegativeButton(init: ActionButtonInit = {}): TemplateResult {\n const { label = 'Cancel' } = init\n return html`<ui-text-button slot=\"button\" type=\"button\" value=\"dismiss\">${label}</ui-text-button>`\n }\n\n /**\n * Renders the submit button for the dialog.\n * If the formId is set, the button will be a submit button.\n * Otherwise, it will be a regular button.\n * @param label The label to use for the submit button.\n */\n protected renderPositiveButton(init: ActionButtonInit = {}): TemplateResult {\n const { label = 'OK', disabled = false } = init\n const { formId } = this\n const type = formId ? 'submit' : 'button'\n // UI buttons have a proper support for form association.\n return html`<ui-text-button\n slot=\"button\"\n ?disabled=\"${disabled}\"\n type=\"${type}\"\n value=\"confirm\"\n form=\"${ifDefined(formId)}\"\n >${label}</ui-text-button\n >`\n }\n\n /**\n * Renders the title for the dialog.\n * @param title The title to render in the dialog.\n */\n protected renderTitle(title: string): TemplateResult {\n return html`<span slot=\"title\">${title}</span>`\n }\n}\n"]}
1
+ {"version":3,"file":"ModalActivity.js","sourceRoot":"","sources":["../../../src/core/ModalActivity.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, type TemplateResult } from 'lit'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { Activity } from './Activity.js'\nimport type { UiDialogClosingReason } from '../md/dialog/internals/Dialog.js'\nimport state from '../decorators/state.js'\nimport { IntentResult } from './ActivityManager.js'\n\nimport '../md/dialog/ui-dialog.js'\nimport '../md/button/ui-text-button.js'\n\nexport interface ActionButtonInit {\n /**\n * The label to use for the button.\n */\n label?: string\n /**\n * Whether the button is disabled.\n */\n disabled?: boolean\n}\n\n/**\n * A special kind of activity that renders content in a modal dialog.\n * When a modal activity is running the underlying activities are paused.\n *\n * A modal activity uses the UiDialogElement to render its content. The dialog\n * is inserted directly into the `<body>` element of the document and rendered\n * in the top layer. Because of that, the modal activity does not support\n * regular rendering logic. It creates its own render root that is used to render\n * the template.\n */\nexport abstract class ModalActivity extends Activity {\n /**\n * The list of classes to apply to the dialog.\n */\n protected dialogClasses: Record<string, boolean> = {}\n /**\n * Controls dialog visibility without controlling the activity state.\n */\n @state() accessor opened = true\n\n /**\n * The id of the form used to render the dialog.\n */\n protected formId?: string\n\n override onResume(): void | Promise<void> {\n this.renderRoot = document.createElement('div')\n this.renderRoot.classList.add('modal-activity-container')\n document.body.appendChild(this.renderRoot)\n super.onResume()\n this.requestUpdate()\n }\n\n override async finish(): Promise<void> {\n if (this.renderRoot) {\n document.body.removeChild(this.renderRoot)\n this.renderRoot = undefined\n }\n await super.finish()\n }\n\n protected handleDialogClosed(e: CustomEvent<UiDialogClosingReason>): void {\n const { cancelled, value } = e.detail\n if (cancelled) {\n this.handleNegativeAction(value)\n } else {\n this.handlePositiveAction(value)\n }\n }\n\n /**\n * Called when the dialog is closed with a negative action.\n * Override this function to handle the negative action.\n * @param value The value passed to the dialog when it is closed.\n */\n protected handleNegativeAction(value: unknown): void {\n this.setResult(IntentResult.RESULT_CANCELED, value)\n this.finish()\n }\n\n /**\n * Called when the dialog is closed with a positive action.\n * Override this function to handle the positive action.\n * @param value The value passed to the dialog when it is closed.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected handlePositiveAction(value: unknown): void {\n this.finish()\n }\n\n /**\n * Override this method to handle the form submission.\n * @param e The submit event.\n */\n protected handleSubmit(e: SubmitEvent): void {\n e.preventDefault()\n }\n\n /**\n * The function called by the rendered when rendering this dialog.\n * This way, the `render()` function is still used as the primary template provider.\n */\n renderDialog(): TemplateResult {\n const classes = {\n activityDialog: true,\n [this.constructor.name.toLowerCase()]: true,\n ...this.dialogClasses,\n }\n return html`<ui-dialog modal .open=\"${this.opened}\" class=\"${classMap(classes)}\" @close=\"${this.handleDialogClosed}\"\n >${this.render()}</ui-dialog\n >`\n }\n\n /**\n * Used with dialogs that render forms. Override the `handleSubmit` method\n * to handle the form submission.\n * @param content The content to render in the form.\n * @param name Optional form name\n */\n protected renderForm(content: TemplateResult, name?: string): TemplateResult {\n if (!this.formId) {\n this.formId = `form-${this.constructor.name.toLowerCase()}`\n }\n return html`<form\n id=\"${this.formId}\"\n name=\"${ifDefined(name)}\"\n class=\"dialog-content\"\n @submit=\"${this.handleSubmit}\"\n >\n ${content}\n </form>`\n }\n\n /**\n * Renders the cancel button for the dialog.\n * @param label The label to use for the cancel button.\n */\n protected renderNegativeButton(init: ActionButtonInit = {}): TemplateResult {\n const { label = 'Cancel' } = init\n return html`<ui-text-button slot=\"button\" type=\"button\" value=\"dismiss\">${label}</ui-text-button>`\n }\n\n /**\n * Renders the submit button for the dialog.\n * If the formId is set, the button will be a submit button.\n * Otherwise, it will be a regular button.\n * @param label The label to use for the submit button.\n */\n protected renderPositiveButton(init: ActionButtonInit = {}): TemplateResult {\n const { label = 'OK', disabled = false } = init\n const { formId } = this\n const type = formId ? 'submit' : 'button'\n // UI buttons have a proper support for form association.\n return html`<ui-text-button\n slot=\"button\"\n ?disabled=\"${disabled}\"\n type=\"${type}\"\n value=\"confirm\"\n form=\"${ifDefined(formId)}\"\n >${label}</ui-text-button\n >`\n }\n\n /**\n * Renders the title for the dialog.\n * @param title The title to render in the dialog.\n */\n protected renderTitle(title: string): TemplateResult {\n return html`<span slot=\"title\">${title}</span>`\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../../../src/reactive/reactive.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,OAAO,CAAA;CAClB;AAOD,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,EAC7C,IAAI,SAAK,GACR,CAAC,CAiEH;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAQ9D"}
1
+ {"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../../../src/reactive/reactive.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,OAAO,CAAA;CAClB;AAOD,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,EAC7C,IAAI,SAAK,GACR,CAAC,CA2GH;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAQ9D"}
@@ -12,17 +12,59 @@ export function createReactive(target, onChange, path = '') {
12
12
  }
13
13
  const handler = {
14
14
  get(target, prop, receiver) {
15
+ // Retrieve the original value. If 'prop' is a getter, 'receiver' (the proxy) is used as 'this'.
15
16
  const value = Reflect.get(target, prop, receiver);
17
+ // If the retrieved value is a function, bind it to the original 'target' object.
18
+ // This ensures that methods (e.g., Set.prototype.add, Map.prototype.set) are called
19
+ // with the correct 'this' context, which is the original unwrapped object.
20
+ // Special handling for Set and Map mutating methods
21
+ if (target instanceof Set) {
22
+ if (['add', 'delete', 'clear'].includes(String(prop))) {
23
+ return (...args) => {
24
+ const oldValue = new Set(target); // shallow copy before mutation
25
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
26
+ const result = value.apply(target, args);
27
+ onChange({
28
+ path,
29
+ value: target,
30
+ oldValue,
31
+ });
32
+ return result;
33
+ };
34
+ }
35
+ }
36
+ if (target instanceof Map) {
37
+ if (['set', 'delete', 'clear'].includes(String(prop))) {
38
+ return (...args) => {
39
+ const oldValue = new Map(target); // shallow copy before mutation
40
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
41
+ const result = value.apply(target, args);
42
+ onChange({
43
+ path,
44
+ value: target,
45
+ oldValue,
46
+ });
47
+ return result;
48
+ };
49
+ }
50
+ }
51
+ if (typeof value === 'function' && !Array.isArray(target)) {
52
+ // If the value is a function, bind it to the original target object.
53
+ return value.bind(target);
54
+ }
55
+ // If the value is an object (and not null, and not a function due to the check above),
56
+ // then recursively create a reactive proxy for it.
16
57
  if (typeof value === 'object' && value !== null) {
17
58
  const finalPath = path ? `${path}.${String(prop)}` : String(prop);
18
59
  return createReactive(value, onChange, finalPath);
19
60
  }
61
+ // For primitive values or null, return the value directly.
20
62
  return value;
21
63
  },
22
64
  set(target, prop, value, receiver) {
23
65
  const oldValue = Reflect.get(target, prop, receiver);
24
66
  const success = Reflect.set(target, prop, value); // do not set the receiver here
25
- // he receiver is the proxy itself and if we set the value on the proxy, it will
67
+ // The receiver is the proxy itself and if we set the value on the proxy, it will
26
68
  // create an infinite loop.
27
69
  if (success && oldValue !== value) {
28
70
  // Check if the old value was proxied and remove it from the cache
@@ -1 +1 @@
1
- {"version":3,"file":"reactive.js","sourceRoot":"","sources":["../../../src/reactive/reactive.ts"],"names":[],"mappings":"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","sourcesContent":["export interface ChangeEventDetail {\n path: string\n value: unknown\n oldValue: unknown\n}\n\n// target -> Proxy\nconst cachedRaw = new WeakMap<object, object>()\n// Proxy -> target\nconst cachedProxies = new WeakMap<object, object>()\n\nexport function createReactive<T extends object>(\n target: T,\n onChange: (detail: ChangeEventDetail) => void,\n path = ''\n): T {\n if (cachedRaw.has(target)) {\n // return target\n return cachedRaw.get(target) as T // Return existing proxy\n }\n if (cachedProxies.has(target)) {\n return target\n }\n\n const handler: ProxyHandler<T> = {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver)\n if (typeof value === 'object' && value !== null) {\n const finalPath = path ? `${path}.${String(prop)}` : String(prop)\n return createReactive(value, onChange, finalPath)\n }\n return value\n },\n set(target, prop, value, receiver) {\n const oldValue = Reflect.get(target, prop, receiver)\n const success = Reflect.set(target, prop, value) // do not set the receiver here\n // he receiver is the proxy itself and if we set the value on the proxy, it will\n // create an infinite loop.\n if (success && oldValue !== value) {\n // Check if the old value was proxied and remove it from the cache\n if (typeof oldValue === 'object' && oldValue !== null) {\n const oldProxy = cachedRaw.get(oldValue)\n if (oldProxy) {\n cachedRaw.delete(oldValue)\n cachedProxies.delete(oldProxy)\n }\n }\n onChange({\n path: path ? `${path}.${String(prop)}` : String(prop),\n value,\n oldValue,\n })\n }\n return success\n },\n deleteProperty(target, prop) {\n const oldValue = Reflect.get(target, prop)\n const success = Reflect.deleteProperty(target, prop)\n if (success) {\n // Check if the old value was proxied and remove it from the cache\n if (typeof oldValue === 'object' && oldValue !== null) {\n const oldProxy = cachedRaw.get(oldValue)\n if (oldProxy) {\n cachedRaw.delete(oldValue)\n cachedProxies.delete(oldProxy)\n }\n }\n onChange({\n path: path ? `${path}.${String(prop)}` : String(prop),\n value: undefined,\n oldValue,\n })\n }\n return success\n },\n }\n const proxy = new Proxy(target, handler)\n cachedRaw.set(target, proxy)\n cachedProxies.set(proxy, target)\n return proxy\n}\n\n/**\n * Removes the proxy and cleans up the cached data.\n *\n * @param reactiveObject The reactive object to unhook.\n * @returns true if the object was reactive and was unhooked, false otherwise.\n */\nexport function unhookReactive(reactiveObject: object): boolean {\n const raw = cachedProxies.get(reactiveObject)\n if (!raw) {\n return false // Not a reactive object\n }\n cachedRaw.delete(raw)\n cachedProxies.delete(reactiveObject)\n return true\n}\n"]}
1
+ {"version":3,"file":"reactive.js","sourceRoot":"","sources":["../../../src/reactive/reactive.ts"],"names":[],"mappings":"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","sourcesContent":["export interface ChangeEventDetail {\n path: string\n value: unknown\n oldValue: unknown\n}\n\n// target -> Proxy\nconst cachedRaw = new WeakMap<object, object>()\n// Proxy -> target\nconst cachedProxies = new WeakMap<object, object>()\n\nexport function createReactive<T extends object>(\n target: T,\n onChange: (detail: ChangeEventDetail) => void,\n path = ''\n): T {\n if (cachedRaw.has(target)) {\n // return target\n return cachedRaw.get(target) as T // Return existing proxy\n }\n if (cachedProxies.has(target)) {\n return target\n }\n\n const handler: ProxyHandler<T> = {\n get(target, prop, receiver) {\n // Retrieve the original value. If 'prop' is a getter, 'receiver' (the proxy) is used as 'this'.\n const value = Reflect.get(target, prop, receiver)\n // If the retrieved value is a function, bind it to the original 'target' object.\n // This ensures that methods (e.g., Set.prototype.add, Map.prototype.set) are called\n // with the correct 'this' context, which is the original unwrapped object.\n // Special handling for Set and Map mutating methods\n if (target instanceof Set) {\n if (['add', 'delete', 'clear'].includes(String(prop))) {\n return (...args: unknown[]) => {\n const oldValue = new Set(target) // shallow copy before mutation\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const result = (value as Function).apply(target, args)\n onChange({\n path,\n value: target,\n oldValue,\n })\n return result\n }\n }\n }\n if (target instanceof Map) {\n if (['set', 'delete', 'clear'].includes(String(prop))) {\n return (...args: unknown[]) => {\n const oldValue = new Map(target) // shallow copy before mutation\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const result = (value as Function).apply(target, args)\n onChange({\n path,\n value: target,\n oldValue,\n })\n return result\n }\n }\n }\n if (typeof value === 'function' && !Array.isArray(target)) {\n // If the value is a function, bind it to the original target object.\n return value.bind(target)\n }\n // If the value is an object (and not null, and not a function due to the check above),\n // then recursively create a reactive proxy for it.\n if (typeof value === 'object' && value !== null) {\n const finalPath = path ? `${path}.${String(prop)}` : String(prop)\n return createReactive(value, onChange, finalPath)\n }\n // For primitive values or null, return the value directly.\n return value\n },\n set(target, prop, value, receiver) {\n const oldValue = Reflect.get(target, prop, receiver)\n const success = Reflect.set(target, prop, value) // do not set the receiver here\n // The receiver is the proxy itself and if we set the value on the proxy, it will\n // create an infinite loop.\n if (success && oldValue !== value) {\n // Check if the old value was proxied and remove it from the cache\n if (typeof oldValue === 'object' && oldValue !== null) {\n const oldProxy = cachedRaw.get(oldValue)\n if (oldProxy) {\n cachedRaw.delete(oldValue)\n cachedProxies.delete(oldProxy)\n }\n }\n onChange({\n path: path ? `${path}.${String(prop)}` : String(prop),\n value,\n oldValue,\n })\n }\n return success\n },\n deleteProperty(target, prop) {\n const oldValue = Reflect.get(target, prop)\n const success = Reflect.deleteProperty(target, prop)\n if (success) {\n // Check if the old value was proxied and remove it from the cache\n if (typeof oldValue === 'object' && oldValue !== null) {\n const oldProxy = cachedRaw.get(oldValue)\n if (oldProxy) {\n cachedRaw.delete(oldValue)\n cachedProxies.delete(oldProxy)\n }\n }\n onChange({\n path: path ? `${path}.${String(prop)}` : String(prop),\n value: undefined,\n oldValue,\n })\n }\n return success\n },\n }\n const proxy = new Proxy(target, handler)\n cachedRaw.set(target, proxy)\n cachedProxies.set(proxy, target)\n return proxy\n}\n\n/**\n * Removes the proxy and cleans up the cached data.\n *\n * @param reactiveObject The reactive object to unhook.\n * @returns true if the object was reactive and was unhooked, false otherwise.\n */\nexport function unhookReactive(reactiveObject: object): boolean {\n const raw = cachedProxies.get(reactiveObject)\n if (!raw) {\n return false // Not a reactive object\n }\n cachedRaw.delete(raw)\n cachedProxies.delete(reactiveObject)\n return true\n}\n"]}
@@ -16,6 +16,6 @@
16
16
  <body>
17
17
  <div id="app"></div>
18
18
 
19
- <script type="module" src="./snack.ts"></script>
19
+ <script type="module" src="../../../../.tmp/demo/demo/elements/md/notification/snack.js"></script>
20
20
  </body>
21
21
  </html>
@@ -22,6 +22,8 @@ class ComponentDemoPage extends DemoPage {
22
22
  kind: UserKind,
23
23
  status: 'active',
24
24
  grantType: 'editor',
25
+ created: new Date('2023-01-01T00:00:00Z').getTime(),
26
+ updated: new Date('2023-01-02T00:00:00Z').getTime(),
25
27
  }
26
28
  this.user2 = {
27
29
  key: '2',
@@ -30,6 +32,8 @@ class ComponentDemoPage extends DemoPage {
30
32
  kind: UserKind,
31
33
  status: 'active',
32
34
  grantType: 'editor',
35
+ created: new Date('2023-01-01T00:00:00Z').getTime(),
36
+ updated: new Date('2023-01-02T00:00:00Z').getTime(),
33
37
  }
34
38
  }
35
39
 
package/eslint.config.js CHANGED
@@ -72,6 +72,9 @@ export default [
72
72
  'no-multi-spaces': ['error'],
73
73
  'no-console': ['error'],
74
74
  'no-redeclare': ['error'],
75
+ '@typescript-eslint/prefer-literal-enum-member': ['error', {
76
+ allowBitwiseExpressions: true,
77
+ }],
75
78
  },
76
79
  },
77
80
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api-client/ui",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Internal UI component library for the API Client ecosystem.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "build/src/index.js",
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-vars */
2
2
  import { nothing, TemplateResult } from 'lit'
3
- import { ActivityState, IntentResult, type Intent } from './ActivityManager.js'
3
+ import { ActivityLifecycle, IntentResult, type Intent } from './ActivityManager.js'
4
4
  import { FragmentManager } from './FragmentManager.js'
5
5
  import type { Fragment } from './Fragment.js'
6
6
  import type { Application, UpdateRequest } from './Application.js'
@@ -36,7 +36,7 @@ export class Activity extends EventTarget {
36
36
  */
37
37
  static action?: string
38
38
 
39
- public state: ActivityState = ActivityState.Initialized
39
+ public lifecycle: ActivityLifecycle = ActivityLifecycle.Initialized
40
40
  protected parent: Application
41
41
  /**
42
42
  * The fragment manager that manages fragments in this activity.
@@ -2,13 +2,41 @@ import type { Activity } from './Activity.js'
2
2
  import type { Application } from './Application.js'
3
3
  import { navigateScreen } from './ApplicationRoute.js'
4
4
 
5
- export enum ActivityState {
5
+ export enum ActivityLifecycle {
6
+ /**
7
+ * The activity is initialized, but not yet created.
8
+ * This is the initial state of the activity.
9
+ */
6
10
  Initialized,
11
+ /**
12
+ * The activity is created, but not yet started.
13
+ * This is the state after the `onCreate()` method is called.
14
+ */
7
15
  Created,
16
+ /**
17
+ * The activity is started, but not yet resumed.
18
+ * This is the state after the `onStart()` method is called.
19
+ */
8
20
  Started,
21
+ /**
22
+ * The activity is resumed and visible to the user.
23
+ * This is the state after the `onResume()` method is called.
24
+ */
9
25
  Resumed,
26
+ /**
27
+ * The activity is paused, but still visible to the user.
28
+ * This is the state after the `onPause()` method is called.
29
+ */
10
30
  Paused,
31
+ /**
32
+ * The activity is stopped and no longer visible to the user.
33
+ * This is the state after the `onStop()` method is called.
34
+ */
11
35
  Stopped,
36
+ /**
37
+ * The activity is destroyed and no longer exists.
38
+ * This is the state after the `onDestroy()` method is called.
39
+ */
12
40
  Destroyed,
13
41
  }
14
42
 
@@ -16,12 +44,10 @@ export enum IntentFlags {
16
44
  /**
17
45
  * Marks that the activity should be rendered as a modal.
18
46
  */
19
- // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
20
47
  Modal = 1 << 0,
21
48
  /**
22
49
  * The activity is started for result.
23
50
  */
24
- // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
25
51
  ForResult = 1 << 1,
26
52
  /**
27
53
  * When set, the intent data is passed by reference.
@@ -29,7 +55,6 @@ export enum IntentFlags {
29
55
  * This is useful when the data is large and you want to avoid copying it
30
56
  * or when you want to share the same data between activities.
31
57
  */
32
- // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
33
58
  ByReference = 1 << 2,
34
59
  }
35
60
 
@@ -178,14 +203,13 @@ export class ActivityManager {
178
203
  await info.activity.onNewIntent(intent)
179
204
  // TODO: Check if the activity is destroyed.
180
205
  this.setupRoute(intent)
181
- // this.currentActivity = info.activity
182
206
  await this.updateCurrentActivity(info.activity, false)
183
207
  return
184
208
  }
185
209
  const activity = this.buildActivity(intent)
186
210
  if (currentActivity) {
187
211
  await currentActivity.onPause()
188
- currentActivity.state = ActivityState.Paused
212
+ currentActivity.lifecycle = ActivityLifecycle.Paused
189
213
  }
190
214
 
191
215
  const activityId = this.generateActivityId()
@@ -204,7 +228,7 @@ export class ActivityManager {
204
228
  // the activity finished and the manager already took care of this situation.
205
229
  return
206
230
  }
207
- activity.state = ActivityState.Created
231
+ activity.lifecycle = ActivityLifecycle.Created
208
232
 
209
233
  await this.updateCurrentActivity(activity, !!isModal)
210
234
  if (this.isDestroyed(activity)) {
@@ -257,7 +281,7 @@ export class ActivityManager {
257
281
  }
258
282
 
259
283
  isDestroyed(activity: Activity): boolean {
260
- return activity.state === ActivityState.Destroyed
284
+ return activity.lifecycle === ActivityLifecycle.Destroyed
261
285
  }
262
286
 
263
287
  /**
@@ -272,23 +296,23 @@ export class ActivityManager {
272
296
  const stackEntry = stack.splice(index, 1)[0]
273
297
 
274
298
  await stackEntry.activity.onPause()
275
- stackEntry.activity.state = ActivityState.Paused
299
+ stackEntry.activity.lifecycle = ActivityLifecycle.Paused
276
300
  await stackEntry.activity.onStop()
277
- stackEntry.activity.state = ActivityState.Stopped
301
+ stackEntry.activity.lifecycle = ActivityLifecycle.Stopped
278
302
  await stackEntry.activity.onDestroy()
279
- stackEntry.activity.state = ActivityState.Destroyed
303
+ stackEntry.activity.lifecycle = ActivityLifecycle.Destroyed
280
304
 
281
305
  await this.manageActivityResult(stackEntry.activity, stackEntry.intent)
282
306
 
283
307
  // Resume the previous activity
284
308
  await this.bringLastActivityToFront()
285
309
  } else {
286
- if (activity.state === ActivityState.Created) {
310
+ if (activity.lifecycle === ActivityLifecycle.Created) {
287
311
  await activity.onStop()
288
- activity.state = ActivityState.Stopped
312
+ activity.lifecycle = ActivityLifecycle.Stopped
289
313
  }
290
314
  await activity.onDestroy()
291
- activity.state = ActivityState.Destroyed
315
+ activity.lifecycle = ActivityLifecycle.Destroyed
292
316
  // This can happen when an activity finishes in one of the callback methods,
293
317
  // before it is added to the stack. In that case, we bring the last activity back to the front.
294
318
  await this.bringLastActivityToFront()
@@ -302,12 +326,12 @@ export class ActivityManager {
302
326
  const all = [...this.activityStack, ...this.modalActivityStack]
303
327
  const target = all.find((entry) => entry.activity.hasRequestCode(requestCode))
304
328
  if (target) {
305
- if (target.activity.state === ActivityState.Destroyed) {
329
+ if (target.activity.lifecycle === ActivityLifecycle.Destroyed) {
306
330
  return
307
331
  }
308
- if (target.activity.state === ActivityState.Resumed) {
332
+ if (target.activity.lifecycle === ActivityLifecycle.Resumed) {
309
333
  await target.activity.onPause()
310
- target.activity.state = ActivityState.Paused
334
+ target.activity.lifecycle = ActivityLifecycle.Paused
311
335
  }
312
336
  const intentCopy = structuredClone(intent)
313
337
  intentCopy.data = activity.getResult()
@@ -329,11 +353,11 @@ export class ActivityManager {
329
353
  }
330
354
 
331
355
  getTopActivity(): Activity | undefined {
332
- const topModal = this.modalActivityStack.findLast((a) => a.activity.state === ActivityState.Resumed)
356
+ const topModal = this.modalActivityStack.findLast((a) => a.activity.lifecycle === ActivityLifecycle.Resumed)
333
357
  if (topModal) {
334
358
  return topModal.activity
335
359
  }
336
- const top = this.activityStack.findLast((a) => a.activity.state === ActivityState.Resumed)
360
+ const top = this.activityStack.findLast((a) => a.activity.lifecycle === ActivityLifecycle.Resumed)
337
361
  return top ? top.activity : undefined
338
362
  }
339
363
 
@@ -385,48 +409,48 @@ export class ActivityManager {
385
409
  if (
386
410
  this.currentActivity &&
387
411
  this.currentActivity !== activity &&
388
- this.currentActivity.state !== ActivityState.Destroyed &&
412
+ this.currentActivity.lifecycle !== ActivityLifecycle.Destroyed &&
389
413
  // Make sure we don't pause the current activity if it's already paused.
390
- this.currentActivity.state !== ActivityState.Paused
414
+ this.currentActivity.lifecycle !== ActivityLifecycle.Paused
391
415
  ) {
392
416
  await this.currentActivity.onPause()
393
- this.currentActivity.state = ActivityState.Paused
417
+ this.currentActivity.lifecycle = ActivityLifecycle.Paused
394
418
  }
395
- if (activity.state === ActivityState.Paused) {
419
+ if (activity.lifecycle === ActivityLifecycle.Paused) {
396
420
  await activity.onResume()
397
421
  if (this.isDestroyed(activity)) {
398
422
  return
399
423
  }
400
- activity.state = ActivityState.Resumed
424
+ activity.lifecycle = ActivityLifecycle.Resumed
401
425
  activity.requestUpdate()
402
- } else if (activity.state === ActivityState.Stopped) {
426
+ } else if (activity.lifecycle === ActivityLifecycle.Stopped) {
403
427
  await activity.onRestart()
404
- activity.state = ActivityState.Resumed
405
- } else if (activity.state === ActivityState.Destroyed) {
428
+ activity.lifecycle = ActivityLifecycle.Resumed
429
+ } else if (activity.lifecycle === ActivityLifecycle.Destroyed) {
406
430
  throw new Error(`Invalid state. The activity is already destroyed.`)
407
- } else if (activity.state === ActivityState.Created) {
431
+ } else if (activity.lifecycle === ActivityLifecycle.Created) {
408
432
  await activity.onStart()
409
433
  if (this.isDestroyed(activity)) {
410
434
  return
411
435
  }
412
- activity.state = ActivityState.Started
436
+ activity.lifecycle = ActivityLifecycle.Started
413
437
  await activity.onResume()
414
438
  if (this.isDestroyed(activity)) {
415
439
  return
416
440
  }
417
- activity.state = ActivityState.Resumed
441
+ activity.lifecycle = ActivityLifecycle.Resumed
418
442
  activity.requestUpdate()
419
- } else if (activity.state === ActivityState.Started) {
443
+ } else if (activity.lifecycle === ActivityLifecycle.Started) {
420
444
  await activity.onResume()
421
445
  if (this.isDestroyed(activity)) {
422
446
  return
423
447
  }
424
- activity.state = ActivityState.Resumed
448
+ activity.lifecycle = ActivityLifecycle.Resumed
425
449
  activity.requestUpdate()
426
- } else if (activity.state === ActivityState.Initialized) {
450
+ } else if (activity.lifecycle === ActivityLifecycle.Initialized) {
427
451
  // TODO: Figure out intent passing here.
428
452
  await activity.onCreate()
429
- activity.state = ActivityState.Created
453
+ activity.lifecycle = ActivityLifecycle.Created
430
454
  if (this.isDestroyed(activity)) {
431
455
  // the activity finished and the manager already took care of this situation.
432
456
  return
@@ -435,12 +459,12 @@ export class ActivityManager {
435
459
  if (this.isDestroyed(activity)) {
436
460
  return
437
461
  }
438
- activity.state = ActivityState.Started
462
+ activity.lifecycle = ActivityLifecycle.Started
439
463
  await activity.onResume()
440
464
  if (this.isDestroyed(activity)) {
441
465
  return
442
466
  }
443
- activity.state = ActivityState.Resumed
467
+ activity.lifecycle = ActivityLifecycle.Resumed
444
468
  activity.requestUpdate()
445
469
  }
446
470
  if (!isModal) {
@@ -1,5 +1,5 @@
1
1
  import { nothing, type TemplateResult } from 'lit'
2
- import { ActivityManager, ActivityState } from './ActivityManager.js'
2
+ import { ActivityManager, ActivityLifecycle } from './ActivityManager.js'
3
3
  import type { Activity } from './Activity.js'
4
4
  import { ApplicationRenderer } from './renderer/ApplicationRenderer.js'
5
5
  import { ThemeManager } from './ThemeManager.js'
@@ -159,7 +159,7 @@ export abstract class Application extends EventTarget {
159
159
  render(): TemplateResult | typeof nothing {
160
160
  const currentActivity = this.#activities.getCurrentActivity()
161
161
  // Only render if started or beyond
162
- if (currentActivity && currentActivity.state >= ActivityState.Started) {
162
+ if (currentActivity && currentActivity.lifecycle >= ActivityLifecycle.Started) {
163
163
  return currentActivity.render()
164
164
  }
165
165
  return nothing
@@ -47,7 +47,7 @@ export abstract class ModalActivity extends Activity {
47
47
 
48
48
  override onResume(): void | Promise<void> {
49
49
  this.renderRoot = document.createElement('div')
50
- this.renderRoot.classList.add('modal-activit-container')
50
+ this.renderRoot.classList.add('modal-activity-container')
51
51
  document.body.appendChild(this.renderRoot)
52
52
  super.onResume()
53
53
  this.requestUpdate()
@@ -24,17 +24,59 @@ export function createReactive<T extends object>(
24
24
 
25
25
  const handler: ProxyHandler<T> = {
26
26
  get(target, prop, receiver) {
27
+ // Retrieve the original value. If 'prop' is a getter, 'receiver' (the proxy) is used as 'this'.
27
28
  const value = Reflect.get(target, prop, receiver)
29
+ // If the retrieved value is a function, bind it to the original 'target' object.
30
+ // This ensures that methods (e.g., Set.prototype.add, Map.prototype.set) are called
31
+ // with the correct 'this' context, which is the original unwrapped object.
32
+ // Special handling for Set and Map mutating methods
33
+ if (target instanceof Set) {
34
+ if (['add', 'delete', 'clear'].includes(String(prop))) {
35
+ return (...args: unknown[]) => {
36
+ const oldValue = new Set(target) // shallow copy before mutation
37
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
38
+ const result = (value as Function).apply(target, args)
39
+ onChange({
40
+ path,
41
+ value: target,
42
+ oldValue,
43
+ })
44
+ return result
45
+ }
46
+ }
47
+ }
48
+ if (target instanceof Map) {
49
+ if (['set', 'delete', 'clear'].includes(String(prop))) {
50
+ return (...args: unknown[]) => {
51
+ const oldValue = new Map(target) // shallow copy before mutation
52
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
53
+ const result = (value as Function).apply(target, args)
54
+ onChange({
55
+ path,
56
+ value: target,
57
+ oldValue,
58
+ })
59
+ return result
60
+ }
61
+ }
62
+ }
63
+ if (typeof value === 'function' && !Array.isArray(target)) {
64
+ // If the value is a function, bind it to the original target object.
65
+ return value.bind(target)
66
+ }
67
+ // If the value is an object (and not null, and not a function due to the check above),
68
+ // then recursively create a reactive proxy for it.
28
69
  if (typeof value === 'object' && value !== null) {
29
70
  const finalPath = path ? `${path}.${String(prop)}` : String(prop)
30
71
  return createReactive(value, onChange, finalPath)
31
72
  }
73
+ // For primitive values or null, return the value directly.
32
74
  return value
33
75
  },
34
76
  set(target, prop, value, receiver) {
35
77
  const oldValue = Reflect.get(target, prop, receiver)
36
78
  const success = Reflect.set(target, prop, value) // do not set the receiver here
37
- // he receiver is the proxy itself and if we set the value on the proxy, it will
79
+ // The receiver is the proxy itself and if we set the value on the proxy, it will
38
80
  // create an infinite loop.
39
81
  if (success && oldValue !== value) {
40
82
  // Check if the old value was proxied and remove it from the cache
@@ -1,7 +1,7 @@
1
1
  import { assert } from '@esm-bundle/chai'
2
2
  import { Activity } from '../../src/core/Activity.js'
3
3
  import { Application } from '../../src/core/Application.js'
4
- import { IntentResult, ActivityState } from '../../src/core/ActivityManager.js'
4
+ import { IntentResult, ActivityLifecycle } from '../../src/core/ActivityManager.js'
5
5
  import { fixture, html } from '@open-wc/testing'
6
6
  import { EventTypes } from '../../src/events/EventTypes.js'
7
7
  import sinon from 'sinon'
@@ -102,7 +102,7 @@ describe('Activity Lifecycle and Events', () => {
102
102
  })
103
103
 
104
104
  it('sets the default state', async () => {
105
- assert.equal(activity.state, ActivityState.Initialized)
105
+ assert.equal(activity.lifecycle, ActivityLifecycle.Initialized)
106
106
  })
107
107
 
108
108
  it('sets the default resultCode', async () => {