diff --git a/postprocess_package.js b/postprocess_package.js index 6342da8..a18fe11 100644 --- a/postprocess_package.js +++ b/postprocess_package.js @@ -22,6 +22,10 @@ const replace_tasks = [ regex: /set mat\(.*?\);/s, // opt2 //replacement: `set mat(_: MeshProps['mat']);` replacement: `set mat(_: PropMat);` + }, + { + regex: /Mesh/g, + replacement: `Mesh` } ] }, @@ -40,6 +44,10 @@ const replace_tasks = [ regex: /set mat\(.*?\);/s, // opt2 //replacement: `set mat(_: PointsProps['mat']);` replacement: `set mat(_: PropMat);` + }, + { + regex: /Points/g, + replacement: `Points` } ] } diff --git a/src/lib/components/AmbientLight.svelte b/src/lib/components/AmbientLight.svelte index 40404c0..f320a3b 100644 --- a/src/lib/components/AmbientLight.svelte +++ b/src/lib/components/AmbientLight.svelte @@ -14,9 +14,9 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -43,6 +43,7 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi */ import { browser } from "$app/environment" + type CurrentComponentType = import("./AmbientLight.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -399,14 +400,18 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -423,24 +428,38 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -455,7 +474,13 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } if (ani) ani.destroyAnimation() @@ -464,18 +489,28 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -492,24 +527,38 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -524,7 +573,13 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (light && !light.matrixAutoUpdate) light.updateMatrix() @@ -544,7 +599,13 @@ AmbientLight cannot be used to cast shadows as it doesn't have a direction. Posi $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/Canvas.svelte b/src/lib/components/Canvas.svelte index 7877a2b..53a0aed 100644 --- a/src/lib/components/Canvas.svelte +++ b/src/lib/components/Canvas.svelte @@ -14,7 +14,6 @@ This is a **svelthree** _Canvas_ Component. import { afterUpdate, beforeUpdate, onMount, onDestroy, setContext, createEventDispatcher } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { Raycaster, Vector2, Vector3 } from "three" import type { Object3D } from "three" import { svelthreeStores } from "svelthree/stores" @@ -32,7 +31,7 @@ This is a **svelthree** _Canvas_ Component. import { RaycastArray } from "../utils/RaycastArray" import { writable } from "svelte/store" import type { Writable } from "svelte/store" - import type { SvelthreeSupportedInteractionEvent } from "../types/types-extra" + import type { SvelthreeSupportedInteractionEvent, SvelthreeLifecycleCallback } from "../types/types-extra" /** * SVELTEKIT SSR @@ -44,6 +43,7 @@ This is a **svelthree** _Canvas_ Component. */ import { browser } from "$app/environment" + type CurrentComponentType = import("./Canvas.svelte").default const self = get_current_component() const c_name = get_comp_name(self) const verbose: boolean = verbose_mode() @@ -847,30 +847,97 @@ This is a **svelthree** _Canvas_ Component. } } - onMount(async () => { - if (verbose && log_lc && (log_lc.all || log_lc.om)) console.info(...c_lc(c_name, "onMount")) - if (verbose && log_dev) { - console.debug(...c_dev(c_name, "onMount -> $svelthreeStores[sti]", $svelthreeStores[sti])) - } - }) + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined + + onMount( + onMountReplace + ? () => onMountReplace(self) + : async () => { + if (verbose && log_lc && (log_lc.all || log_lc.om)) { + console.info(...c_lc(c_name, "onMount")) + } + if (verbose && log_dev) { + console.debug(...c_dev(c_name, "onMount -> $svelthreeStores[sti]", $svelthreeStores[sti])) + } + } + ) + + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined - onDestroy(async () => { - if (verbose && log_lc && (log_lc.all || log_lc.od)) console.info(...c_lc(c_name, "onDestroy")) - remove_all_listeners() - // if canvas is being removed set the the whole store to 'null' - // this way we don't have to handle anything, other store 'sti' will remain valid - // any newly added canvas will create a new store at the next highest index - // the value of 'sti' is completely irrelevant to the user, doesn't need to be handled. - $svelthreeStores[sti] = null - - // if all stores are `null` we can safely reset the `svelthreeStores` array, e.g. when switching pages / routes. - if (all_stores_are_null()) { - $svelthreeStores = [] - } else { - // trim `svelthreeStores` array's tail - trim_stores_array() - } - }) + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined + + onDestroy( + onDestroyReplace + ? () => onDestroyReplace(self) + : async () => { + if (verbose && log_lc && (log_lc.all || log_lc.od)) { + console.info(...c_lc(c_name, "onDestroy")) + } + + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } + + remove_all_listeners() + // if canvas is being removed set the the whole store to 'null' + // this way we don't have to handle anything, other store 'sti' will remain valid + // any newly added canvas will create a new store at the next highest index + // the value of 'sti' is completely irrelevant to the user, doesn't need to be handled. + $svelthreeStores[sti] = null + + // if all stores are `null` we can safely reset the `svelthreeStores` array, e.g. when switching pages / routes. + if (all_stores_are_null()) { + $svelthreeStores = [] + } else { + // trim `svelthreeStores` array's tail + trim_stores_array() + } + + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } + } + ) function all_stores_are_null(): boolean { for (let i = 0; i < $svelthreeStores.length; i++) { @@ -899,13 +966,43 @@ This is a **svelthree** _Canvas_ Component. } } - beforeUpdate(async () => { - if (verbose && log_lc && (log_lc.all || log_lc.bu)) console.info(...c_lc(c_name, "beforeUpdate")) - }) - - afterUpdate(async () => { - if (verbose && log_lc && (log_lc.all || log_lc.au)) console.info(...c_lc(c_name, "afterUpdate")) - }) + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined + + beforeUpdate( + beforeUpdateReplace + ? () => beforeUpdateReplace(self) + : async () => { + if (verbose && log_lc && (log_lc.all || log_lc.bu)) { + console.info(...c_lc(c_name, "beforeUpdate")) + } + } + ) + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined + + afterUpdate( + afterUpdateReplace + ? () => afterUpdateReplace(self) + : async () => { + if (verbose && log_lc && (log_lc.all || log_lc.au)) { + console.info(...c_lc(c_name, "afterUpdate")) + } + } + ) diff --git a/src/lib/components/CubeCamera.svelte b/src/lib/components/CubeCamera.svelte index 25d18fb..dc2a64d 100644 --- a/src/lib/components/CubeCamera.svelte +++ b/src/lib/components/CubeCamera.svelte @@ -14,9 +14,9 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -64,6 +64,7 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env */ import { browser } from "$app/environment" + type CurrentComponentType = import("./CubeCamera.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -709,14 +710,18 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -733,24 +738,38 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -765,7 +784,13 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } if (ani) ani.destroyAnimation() @@ -774,18 +799,28 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -802,24 +837,38 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -834,7 +883,13 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (camera && !camera.matrixAutoUpdate) camera.updateMatrix() @@ -854,7 +909,13 @@ Renders a `CubeMap` which can be used with **non-PBR** materials having an `.env $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/DirectionalLight.svelte b/src/lib/components/DirectionalLight.svelte index 26ccb6f..86c1629 100644 --- a/src/lib/components/DirectionalLight.svelte +++ b/src/lib/components/DirectionalLight.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -56,6 +56,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./DirectionalLight.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -540,14 +541,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -564,24 +569,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -596,7 +615,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_helper() if (ani) ani.destroyAnimation() @@ -606,18 +631,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -634,24 +669,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -666,7 +715,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (light && !light.matrixAutoUpdate) light.updateMatrix() @@ -688,7 +743,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/Group.svelte b/src/lib/components/Group.svelte index fa443ad..9f52917 100644 --- a/src/lib/components/Group.svelte +++ b/src/lib/components/Group.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -49,6 +49,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./Group.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -518,14 +519,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -542,24 +547,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -574,7 +593,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_box_helper() if (ani) ani.destroyAnimation() @@ -582,18 +607,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` destroy_registered_child_components(generated_children) destroy_registered_child_components(user_created_children) - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -610,24 +645,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -642,7 +691,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (group && !group.matrixAutoUpdate) group.updateMatrix() @@ -662,7 +717,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/HemisphereLight.svelte b/src/lib/components/HemisphereLight.svelte index 66a9b97..ded3ba4 100644 --- a/src/lib/components/HemisphereLight.svelte +++ b/src/lib/components/HemisphereLight.svelte @@ -13,9 +13,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -44,6 +44,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./HemisphereLight.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -445,14 +446,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -469,24 +474,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -501,7 +520,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_helper() if (ani) ani.destroyAnimation() @@ -511,18 +536,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -539,24 +574,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -571,7 +620,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (light && !light.matrixAutoUpdate) light.updateMatrix() @@ -593,7 +648,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/LoadedGLTF.svelte b/src/lib/components/LoadedGLTF.svelte index c6f08e9..9be66b2 100644 --- a/src/lib/components/LoadedGLTF.svelte +++ b/src/lib/components/LoadedGLTF.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext, tick } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata } from "../logic/shared" @@ -69,6 +69,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./LoadedGLTF.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -825,14 +826,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -849,24 +854,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -881,7 +900,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_box_helper() if (ani) ani.destroyAnimation() @@ -889,18 +914,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` destroy_registered_child_components(generated_children) destroy_registered_child_components(user_created_children) - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -917,24 +952,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -949,7 +998,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (container && !container.matrixAutoUpdate) container.updateMatrix() @@ -969,7 +1024,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/Mesh.svelte b/src/lib/components/Mesh.svelte index 24efb84..55d21fe 100644 --- a/src/lib/components/Mesh.svelte +++ b/src/lib/components/Mesh.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext, tick } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -67,11 +67,6 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" - const self = get_current_component() - const c_name = get_comp_name(self) - /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ - export const type: string = c_name - const verbose: boolean = verbose_mode() export let log_all = false @@ -132,6 +127,12 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export let geometry: BufferGeometry = undefined let geometry_ref: BufferGeometry = undefined + type CurrentComponentType = import("./Mesh.svelte").default + const self = get_current_component() + const c_name = get_comp_name(self) + /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ + export const type: string = c_name + export const is_svelthree_component = true export const is_svelthree_mesh = true @@ -943,14 +944,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -967,24 +972,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -999,7 +1018,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_box_helper() if (ani) ani.destroyAnimation() @@ -1007,18 +1032,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` destroy_registered_child_components(generated_children) destroy_registered_child_components(user_created_children) - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -1035,24 +1070,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -1067,7 +1116,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (mesh && !mesh.matrixAutoUpdate) mesh.updateMatrix() @@ -1087,7 +1142,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/Object3D.svelte b/src/lib/components/Object3D.svelte index c94ff7d..60e2237 100644 --- a/src/lib/components/Object3D.svelte +++ b/src/lib/components/Object3D.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -48,6 +48,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./Object3D.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -518,14 +519,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -542,24 +547,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -574,7 +593,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_box_helper() if (ani) ani.destroyAnimation() @@ -582,18 +607,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` destroy_registered_child_components(generated_children) destroy_registered_child_components(user_created_children) - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -610,24 +645,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -642,7 +691,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (object3d && !object3d.matrixAutoUpdate) object3d.updateMatrix() @@ -662,7 +717,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/OrbitControls.svelte b/src/lib/components/OrbitControls.svelte index 754aa44..153f024 100644 --- a/src/lib/components/OrbitControls.svelte +++ b/src/lib/components/OrbitControls.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import { svelthreeStores } from "svelthree/stores" import { SvelthreeProps } from "../utils" @@ -35,6 +35,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import type { default as OrthographicCamera } from "./OrthographicCamera.svelte" import type { default as Canvas } from "../components/Canvas.svelte" + type CurrentComponentType = import("./OrbitControls.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -269,14 +270,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` /** Returns the (three) instance of the object created by the component. */ export const get_instance = (): THREE_OrbitControls => orbitcontrols - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -284,46 +289,76 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } if (rAF.id) cancelAnimationFrame(rAF.id) orbitcontrols.removeEventListener("change", on_orbitcontrols_change) - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -331,14 +366,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) diff --git a/src/lib/components/OrthographicCamera.svelte b/src/lib/components/OrthographicCamera.svelte index 2b03112..7e045b7 100644 --- a/src/lib/components/OrthographicCamera.svelte +++ b/src/lib/components/OrthographicCamera.svelte @@ -19,9 +19,9 @@ If you use this approach you'll see a warning in the console if you define left, import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -55,6 +55,7 @@ If you use this approach you'll see a warning in the console if you define left, */ import { browser } from "$app/environment" + type CurrentComponentType = import("./OrthographicCamera.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -625,14 +626,18 @@ If you use this approach you'll see a warning in the console if you define left, export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -649,24 +654,38 @@ If you use this approach you'll see a warning in the console if you define left, } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -681,7 +700,13 @@ If you use this approach you'll see a warning in the console if you define left, ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_helper() if (ani) ani.destroyAnimation() @@ -691,18 +716,28 @@ If you use this approach you'll see a warning in the console if you define left, remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -719,24 +754,38 @@ If you use this approach you'll see a warning in the console if you define left, } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -751,7 +800,13 @@ If you use this approach you'll see a warning in the console if you define left, ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (camera && !camera.matrixAutoUpdate) camera.updateMatrix() @@ -778,7 +833,13 @@ If you use this approach you'll see a warning in the console if you define left, $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/PerspectiveCamera.svelte b/src/lib/components/PerspectiveCamera.svelte index a63ba7b..2ac099c 100644 --- a/src/lib/components/PerspectiveCamera.svelte +++ b/src/lib/components/PerspectiveCamera.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -48,6 +48,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./PerspectiveCamera.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -659,14 +660,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -683,24 +688,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -715,7 +734,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_helper() if (ani) ani.destroyAnimation() @@ -725,18 +750,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -753,24 +788,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -785,7 +834,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (camera && !camera.matrixAutoUpdate) camera.updateMatrix() @@ -812,7 +867,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/PointLight.svelte b/src/lib/components/PointLight.svelte index 06f5312..5bfa8f6 100644 --- a/src/lib/components/PointLight.svelte +++ b/src/lib/components/PointLight.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -50,6 +50,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./PointLight.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -503,14 +504,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -527,24 +532,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -559,7 +578,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_helper() if (ani) ani.destroyAnimation() @@ -569,18 +594,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -597,24 +632,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -629,7 +678,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (light && !light.matrixAutoUpdate) light.updateMatrix() @@ -651,7 +706,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/Points.svelte b/src/lib/components/Points.svelte index 9844eec..0302046 100644 --- a/src/lib/components/Points.svelte +++ b/src/lib/components/Points.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext, tick } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -67,11 +67,6 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" - const self = get_current_component() - const c_name = get_comp_name(self) - /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ - export const type: string = c_name - const verbose: boolean = verbose_mode() export let log_all = false @@ -132,6 +127,12 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export let geometry: BufferGeometry = undefined let geometry_ref: BufferGeometry = undefined + type CurrentComponentType = import("./Points.svelte").default + const self = get_current_component() + const c_name = get_comp_name(self) + /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ + export const type: string = c_name + export const is_svelthree_component = true export const is_svelthree_points = true @@ -943,14 +944,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -967,24 +972,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -999,7 +1018,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_box_helper() if (ani) ani.destroyAnimation() @@ -1007,18 +1032,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` destroy_registered_child_components(generated_children) destroy_registered_child_components(user_created_children) - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -1035,24 +1070,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -1067,7 +1116,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (points && !points.matrixAutoUpdate) points.updateMatrix() @@ -1087,7 +1142,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/RectAreaLight.svelte b/src/lib/components/RectAreaLight.svelte index c279f5e..7c47ebe 100644 --- a/src/lib/components/RectAreaLight.svelte +++ b/src/lib/components/RectAreaLight.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -49,6 +49,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./RectAreaLight.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -523,14 +524,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -547,24 +552,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -579,7 +598,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_helper() if (ani) ani.destroyAnimation() @@ -589,18 +614,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -617,24 +652,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -649,7 +698,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (light && !light.matrixAutoUpdate) light.updateMatrix() @@ -671,7 +726,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/Scene.svelte b/src/lib/components/Scene.svelte index 9774e2b..3ba8173 100644 --- a/src/lib/components/Scene.svelte +++ b/src/lib/components/Scene.svelte @@ -12,9 +12,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` diff --git a/src/lib/components/SpotLight.svelte b/src/lib/components/SpotLight.svelte index 398f507..66f6efe 100644 --- a/src/lib/components/SpotLight.svelte +++ b/src/lib/components/SpotLight.svelte @@ -14,9 +14,9 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` import { beforeUpdate, onMount, afterUpdate, onDestroy, getContext, setContext } from "svelte" import { get_current_component } from "svelte/internal" - import { self as _self } from "svelte/internal" import { c_rs, c_lc, c_mau, c_dev, verbose_mode, get_comp_name } from "../utils/SvelthreeLogger" import type { LogLC, LogDEV } from "../utils/SvelthreeLogger" + import type { SvelthreeLifecycleCallback } from "../types/types-extra" import type { SvelthreeShadowDOMElement } from "../types/types-extra" import { if$_instance_change } from "../logic/if$" import { remove_instance, recreate_shadow_dom_el, set_initial_userdata, find_in_canvas } from "../logic/shared" @@ -52,6 +52,7 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` */ import { browser } from "$app/environment" + type CurrentComponentType = import("./SpotLight.svelte").default const self = get_current_component() const c_name = get_comp_name(self) /** svelthree component's type (e.g. component `Foo` is of type 'Foo' etc.) */ @@ -581,14 +582,18 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` export const get_user_created_children = (): SvelthreeComponentShadowDOMChild[] => user_created_children export const get_generated_children = (): SvelthreeComponentShadowDOMChild[] => generated_children - /** **Completely replace** `onMount` -> any `onMount_inject_before` & `onMount_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onMount_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `onMount`-callback logic, any `onMountStart` & `onMountEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onMountReplace: SvelthreeLifecycleCallback = undefined onMount( - onMount_replace - ? async () => onMount_replace(_self) + onMountReplace + ? () => onMountReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.om)) { console.info(...c_lc(c_name, "onMount")) @@ -605,24 +610,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `onDestroy` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `onDestroy` -> any `onDestroy_inject_before` & `onDestroy_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let onDestroy_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `onDestroy`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `onDestroy`-callback logic, any `onDestroyStart` & `onDestroyEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let onDestroyReplace: SvelthreeLifecycleCallback = undefined onDestroy( - onDestroy_replace - ? async () => onDestroy_replace(_self) + onDestroyReplace + ? () => onDestroyReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.od)) { console.info(...c_lc(c_name, "onDestroy")) @@ -637,7 +656,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (onDestroy_inject_before) onDestroy_inject_before() + if (onDestroyStart) { + if (onDestroyStart.constructor.name === "AsyncFunction") { + await onDestroyStart(self) + } else { + onDestroyStart(self) + } + } remove_helper() if (ani) ani.destroyAnimation() @@ -647,18 +672,28 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` remove_instance_from_parent() - if (onDestroy_inject_after) onDestroy_inject_after() + if (onDestroyEnd) { + if (onDestroyEnd.constructor.name === "AsyncFunction") { + await onDestroyEnd(self) + } else { + onDestroyEnd(self) + } + } } ) - /** **Completely replace** `beforeUpdate` -> any `beforeUpdate_inject_before` & `beforeUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let beforeUpdate_replace: (args?: any) => any = undefined + /** **Completely replace** `svelthree`-component's default `beforeUpdate`-callback logic, any `beforeUpdateStart` & `beforeUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let beforeUpdateReplace: SvelthreeLifecycleCallback = undefined beforeUpdate( - beforeUpdate_replace - ? async () => beforeUpdate_replace(_self) + beforeUpdateReplace + ? () => beforeUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.bu)) { console.info(...c_lc(c_name, "beforeUpdate")) @@ -675,24 +710,38 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` } ) - /** **Inject** functionality **before** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_before: (args?: any) => any = undefined - - /** **Inject** functionality **after** component's existing `afterUpdate` logic. - * _default verbosity not affected._ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_inject_after: (args?: any) => any = undefined - - /** **Completely replace** `afterUpdate` -> any `afterUpdate_inject_before` & `afterUpdate_inject_after` will be ignored. - * _default verbosity will be gone!_ */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - export let afterUpdate_replace: (args?: any) => any = undefined + /** **Inject** functionality at the **start** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateStart: SvelthreeLifecycleCallback = undefined + + /** **Inject** functionality at the **end** of `svelthree`-component's default `afterUpdate`-callback logic (`asynchronous`). + * Only asynchronous functions will be `await`ed. (_default verbosity will not be affected_) + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateEnd: SvelthreeLifecycleCallback = undefined + + /** **Completely replace** `svelthree`-component's default `afterUpdate`-callback logic, any `afterUpdateStart` & `afterUpdateEnd` logic will be ignored (_default verbosity will be gone_). + * + * **Accepts** a `SvelthreeLifecycleCallback`-type function as a **value**, which can also be explicitly typed as a **synchronous** (_type `SvelthreeLifecycleCallbackSync`_) or an **asynchronous** (_type `SvelthreeLifecycleCallbackAsync`_) callback: + * ```ts + * (comp: T) => unknown | Promise + * ``` + * ☝️ _the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_. */ + export let afterUpdateReplace: SvelthreeLifecycleCallback = undefined afterUpdate( - afterUpdate_replace - ? async () => afterUpdate_replace(_self) + afterUpdateReplace + ? () => afterUpdateReplace(self) : async () => { if (verbose && log_lc && (log_lc.all || log_lc.au)) { console.info(...c_lc(c_name, "afterUpdate")) @@ -707,7 +756,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` ) } - if (afterUpdate_inject_before) afterUpdate_inject_before() + if (afterUpdateStart) { + if (afterUpdateStart.constructor.name === "AsyncFunction") { + await afterUpdateStart(self) + } else { + afterUpdateStart(self) + } + } // Update local matrix after all (props) changes (async microtasks) have been applied. if (light && !light.matrixAutoUpdate) light.updateMatrix() @@ -729,7 +784,13 @@ svelthree uses svelte-accmod, where accessors are always `true`, regardless of ` $svelthreeStores[sti].rendererComponent.schedule_render_auto(root_scene) } - if (afterUpdate_inject_after) afterUpdate_inject_after() + if (afterUpdateEnd) { + if (afterUpdateEnd.constructor.name === "AsyncFunction") { + await afterUpdateEnd(self) + } else { + afterUpdateEnd(self) + } + } } ) diff --git a/src/lib/components/WebGLRenderer.svelte b/src/lib/components/WebGLRenderer.svelte index 04f8801..df6e628 100644 --- a/src/lib/components/WebGLRenderer.svelte +++ b/src/lib/components/WebGLRenderer.svelte @@ -12,7 +12,6 @@ This is a **svelthree** _WebGLRenderer_ Component. diff --git a/src/lib/index.ts b/src/lib/index.ts index 650167b..f2dd811 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -77,7 +77,13 @@ export type { PropLink, PropButton, PropWebGLRenderTargetOptions } from "./types // TODO config // misc -export type { Targetable, TargetableSvelthreeComponent } from "./types/types-extra" +export type { + Targetable, + TargetableSvelthreeComponent, + SvelthreeLifecycleCallback, + SvelthreeLifecycleCallbackAsync, + SvelthreeLifecycleCallbackSync +} from "./types/types-extra" // Animation related export type { SvelthreeAnimationFunction, SvelthreeAnimation } from "./types/types-extra" diff --git a/src/lib/types/types-extra.ts b/src/lib/types/types-extra.ts index 185503b..477becd 100644 --- a/src/lib/types/types-extra.ts +++ b/src/lib/types/types-extra.ts @@ -542,3 +542,57 @@ export type SvelthreeKeyboardEventHandler = export type SvelthreeWheelEventHandler = | [handler: (e: CustomEvent) => void, modifiers?: Array] | ((e: SvelthreeInteractionEvent) => void) + +/** An explicitly **asynchoronous** callback-function + * ```ts + * (comp: T) => Promise + * ``` + * (_the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_) + * which can be used as a value for `svelthree`-component's additional lifecycle-callback-attributes: + * - `onMountReplace` + * - `onDestroyReplace` + * - `onDestroyStart` (_if available_) + * - `onDestroyEnd` (_if available_) + * - `beforeUpdateReplace` + * - `afterUpdateReplace` + * - `afterUpdateStart` (_if available_) + * - `afterUpdateEnd` (_if available_) + * + */ +export type SvelthreeLifecycleCallbackAsync = (comp: T) => Promise + +/** An explicitly **synchronous** callback-function + * ```ts + * (comp: T) => unknown + * ``` + * (_the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_) + * which can be used as a value for `svelthree`-component's additional lifecycle-callback-attributes: + * - `onMountReplace` + * - `onDestroyReplace` + * - `onDestroyStart` (_if available_) + * - `onDestroyEnd` (_if available_) + * - `beforeUpdateReplace` + * - `afterUpdateReplace` + * - `afterUpdateStart` (_if available_) + * - `afterUpdateEnd` (_if available_) + * + */ +export type SvelthreeLifecycleCallbackSync = (comp: T) => unknown + +/** A **synchoronous** or **asynchoronous** callback-function + * ```ts + * (comp: T) => unknown | Promise + * ``` + * (_the **callback's argument** (`comp`) will be the actual **`svelthree`-component's instance reference**_) + * which can be used as a value for `svelthree`-component's additional lifecycle-callback-attributes: + * - `onMountReplace` + * - `onDestroyReplace` + * - `onDestroyStart` (_if available_) + * - `onDestroyEnd` (_if available_) + * - `beforeUpdateReplace` + * - `afterUpdateReplace` + * - `afterUpdateStart` (_if available_) + * - `afterUpdateEnd` (_if available_) + * + */ +export type SvelthreeLifecycleCallback = SvelthreeLifecycleCallbackSync | SvelthreeLifecycleCallbackAsync