@studiometa/js-toolkit 4.0.0-alpha.1 → 4.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/Base.d.ts +0 -2
- package/dist/Base.js +1 -2
- package/dist/Base.js.map +1 -1
- package/dist/attribute-namespaces.d.ts +0 -2
- package/dist/attribute-namespaces.js +1 -2
- package/dist/attributes.d.ts +0 -2
- package/dist/attributes.js +1 -2
- package/dist/children-watchers.d.ts +0 -2
- package/dist/children-watchers.js +1 -2
- package/dist/component-brand.d.ts +0 -2
- package/dist/component-brand.js +1 -2
- package/dist/component-declarations.d.ts +0 -2
- package/dist/component-declarations.js +1 -2
- package/dist/context-subscription.d.ts +0 -2
- package/dist/context-subscription.js +1 -2
- package/dist/context.d.ts +0 -2
- package/dist/context.js +1 -2
- package/dist/decorators.d.ts +0 -2
- package/dist/decorators.js +1 -2
- package/dist/diagnostic-contract.d.ts +0 -2
- package/dist/diagnostic-contract.js +1 -2
- package/dist/diagnostics.d.ts +0 -2
- package/dist/diagnostics.js +1 -2
- package/dist/document-order.d.ts +0 -2
- package/dist/document-order.js +1 -2
- package/dist/dom-mutations.d.ts +0 -2
- package/dist/dom-mutations.js +1 -2
- package/dist/events.d.ts +0 -2
- package/dist/events.js +1 -2
- package/dist/group.d.ts +0 -2
- package/dist/group.js +1 -2
- package/dist/instances.d.ts +0 -2
- package/dist/instances.js +1 -2
- package/dist/manifest.d.ts +0 -2
- package/dist/manifest.js +1 -2
- package/dist/mount-strategies.d.ts +0 -2
- package/dist/mount-strategies.js +1 -2
- package/dist/negotiated-events.d.ts +0 -2
- package/dist/negotiated-events.js +1 -2
- package/dist/protocol-symbols.d.ts +0 -2
- package/dist/protocol-symbols.js +1 -2
- package/dist/registry.d.ts +0 -2
- package/dist/registry.js +1 -2
- package/dist/responsive-options.d.ts +0 -2
- package/dist/responsive-options.js +1 -2
- package/dist/scheduler.d.ts +0 -2
- package/dist/scheduler.js +1 -2
- package/dist/scheduler.js.map +1 -1
- package/dist/services/breakpoint.d.ts +0 -2
- package/dist/services/breakpoint.js +1 -2
- package/dist/services/drag.d.ts +0 -2
- package/dist/services/drag.js +1 -2
- package/dist/services/in-view.d.ts +0 -2
- package/dist/services/in-view.js +1 -2
- package/dist/services/key.d.ts +0 -2
- package/dist/services/key.js +1 -2
- package/dist/services/media.d.ts +0 -2
- package/dist/services/media.js +1 -2
- package/dist/services/mixin.d.ts +0 -2
- package/dist/services/mixin.js +1 -2
- package/dist/services/mutation.d.ts +0 -2
- package/dist/services/mutation.js +1 -2
- package/dist/services/pointer.d.ts +0 -2
- package/dist/services/pointer.js +1 -2
- package/dist/services/raf.d.ts +0 -2
- package/dist/services/raf.js +1 -2
- package/dist/services/resize.d.ts +0 -2
- package/dist/services/resize.js +1 -2
- package/dist/services/scroll-progress-offset.d.ts +0 -2
- package/dist/services/scroll-progress-offset.js +1 -2
- package/dist/services/scroll-progress.d.ts +0 -2
- package/dist/services/scroll-progress.js +1 -2
- package/dist/services/scroll.d.ts +0 -2
- package/dist/services/scroll.js +1 -2
- package/dist/services/service.d.ts +0 -2
- package/dist/services/service.js +1 -2
- package/dist/services/toggle.d.ts +0 -2
- package/dist/services/toggle.js +1 -2
- package/dist/services/until.d.ts +0 -2
- package/dist/services/until.js +1 -2
- package/dist/shared-runtime.d.ts +0 -2
- package/dist/shared-runtime.js +1 -2
- package/dist/storage/createStorage.d.ts +0 -2
- package/dist/storage/createStorage.js +1 -2
- package/dist/storage/index.d.ts +0 -2
- package/dist/storage/index.js +1 -2
- package/dist/storage/providers.d.ts +0 -2
- package/dist/storage/providers.js +1 -2
- package/dist/storage/serializers.d.ts +0 -2
- package/dist/storage/serializers.js +1 -2
- package/dist/storage/sync.d.ts +0 -2
- package/dist/storage/sync.js +1 -2
- package/dist/storage/types.d.ts +0 -2
- package/dist/subpaths/BREAKPOINTS.js +1 -2
- package/dist/subpaths/Base.js +1 -2
- package/dist/subpaths/DIAGNOSTICS.js +1 -2
- package/dist/subpaths/DRAG_MODES.js +1 -2
- package/dist/subpaths/EVENTS.js +1 -2
- package/dist/subpaths/MOUNT_ATTRIBUTE.js +1 -2
- package/dist/subpaths/SWAP_MODES.js +1 -2
- package/dist/subpaths/children.js +1 -2
- package/dist/subpaths/component.js +1 -2
- package/dist/subpaths/createContext.js +1 -2
- package/dist/subpaths/createFallbackProvider.js +1 -2
- package/dist/subpaths/createGroup.js +1 -2
- package/dist/subpaths/createLocalStorage.js +1 -2
- package/dist/subpaths/createMemoryStorageProvider.js +1 -2
- package/dist/subpaths/createService.js +1 -2
- package/dist/subpaths/createServiceMixin.js +1 -2
- package/dist/subpaths/createSessionStorage.js +1 -2
- package/dist/subpaths/createStorage.js +1 -2
- package/dist/subpaths/createUrlSearchParamsInHashProvider.js +1 -2
- package/dist/subpaths/createUrlSearchParamsInHashStorage.js +1 -2
- package/dist/subpaths/createUrlSearchParamsProvider.js +1 -2
- package/dist/subpaths/createUrlSearchParamsStorage.js +1 -2
- package/dist/subpaths/defaultScheduler.js +1 -2
- package/dist/subpaths/defineManifest.js +1 -2
- package/dist/subpaths/domUpdate.js +1 -2
- package/dist/subpaths/emitExtendable.js +1 -2
- package/dist/subpaths/fromMetaGlob.js +1 -2
- package/dist/subpaths/fromWebpackContext.js +1 -2
- package/dist/subpaths/getBreakpoints.js +1 -2
- package/dist/subpaths/getInstance.js +1 -2
- package/dist/subpaths/getInstances.js +1 -2
- package/dist/subpaths/getMountedInstances.js +1 -2
- package/dist/subpaths/getUnmountedInstances.js +1 -2
- package/dist/subpaths/inject.js +1 -2
- package/dist/subpaths/injectContext.js +1 -2
- package/dist/subpaths/injectContextSync.js +1 -2
- package/dist/subpaths/jsonSerializer.js +1 -2
- package/dist/subpaths/localStorageProvider.js +1 -2
- package/dist/subpaths/memoryStorageProvider.js +1 -2
- package/dist/subpaths/namespaceQualifier.js +1 -2
- package/dist/subpaths/nextFrame.js +1 -2
- package/dist/subpaths/on.js +1 -2
- package/dist/subpaths/perTarget.js +1 -2
- package/dist/subpaths/provide.js +1 -2
- package/dist/subpaths/provideContext.js +1 -2
- package/dist/subpaths/provideRootContext.js +1 -2
- package/dist/subpaths/read.js +1 -2
- package/dist/subpaths/registerComponent.js +1 -2
- package/dist/subpaths/registerComponents.js +1 -2
- package/dist/subpaths/registerManifest.js +1 -2
- package/dist/subpaths/reportDiagnostic.js +1 -2
- package/dist/subpaths/sessionStorageProvider.js +1 -2
- package/dist/subpaths/setBreakpoints.js +1 -2
- package/dist/subpaths/signal.js +1 -2
- package/dist/subpaths/subscribeContext.js +1 -2
- package/dist/subpaths/swap.js +1 -2
- package/dist/subpaths/toggle.js +1 -2
- package/dist/subpaths/until.js +1 -2
- package/dist/subpaths/urlSearchParamsInHashProvider.js +1 -2
- package/dist/subpaths/urlSearchParamsProvider.js +1 -2
- package/dist/subpaths/useBreakpoint.js +1 -2
- package/dist/subpaths/useDrag.js +1 -2
- package/dist/subpaths/useInView.js +1 -2
- package/dist/subpaths/useKey.js +1 -2
- package/dist/subpaths/useMediaQuery.js +1 -2
- package/dist/subpaths/useMutation.js +1 -2
- package/dist/subpaths/usePointer.js +1 -2
- package/dist/subpaths/usePrefersReducedMotion.js +1 -2
- package/dist/subpaths/useRaf.js +1 -2
- package/dist/subpaths/useResize.js +1 -2
- package/dist/subpaths/useScroll.js +1 -2
- package/dist/subpaths/useScrollProgress.js +1 -2
- package/dist/subpaths/useWindowScroll.js +1 -2
- package/dist/subpaths/useWindowSize.js +1 -2
- package/dist/subpaths/utils/DEFAULT_DAMP_FACTOR.js +1 -2
- package/dist/subpaths/utils/INERTIA_FRAME.js +1 -2
- package/dist/subpaths/utils/MAX_SPRING_RATIO.js +1 -2
- package/dist/subpaths/utils/SCROLL_ALIGNMENTS.js +1 -2
- package/dist/subpaths/utils/SCROLL_AXES.js +1 -2
- package/dist/subpaths/utils/TRANSFORM_PROPS.js +1 -2
- package/dist/subpaths/utils/TRANSITION_OPTIONS.js +1 -2
- package/dist/subpaths/utils/camelCase.js +1 -2
- package/dist/subpaths/utils/capitalize.js +1 -2
- package/dist/subpaths/utils/clamp.js +1 -2
- package/dist/subpaths/utils/clamp01.js +1 -2
- package/dist/subpaths/utils/clampDampFactor.js +1 -2
- package/dist/subpaths/utils/createEaseInOut.js +1 -2
- package/dist/subpaths/utils/createEaseOut.js +1 -2
- package/dist/subpaths/utils/createElement.js +1 -2
- package/dist/subpaths/utils/createRange.js +1 -2
- package/dist/subpaths/utils/damp.js +1 -2
- package/dist/subpaths/utils/debounce.js +1 -2
- package/dist/subpaths/utils/decayOver.js +1 -2
- package/dist/subpaths/utils/deepmerge.js +1 -2
- package/dist/subpaths/utils/easeInCirc.js +1 -2
- package/dist/subpaths/utils/easeInCubic.js +1 -2
- package/dist/subpaths/utils/easeInExpo.js +1 -2
- package/dist/subpaths/utils/easeInOutCirc.js +1 -2
- package/dist/subpaths/utils/easeInOutCubic.js +1 -2
- package/dist/subpaths/utils/easeInOutExpo.js +1 -2
- package/dist/subpaths/utils/easeInOutQuad.js +1 -2
- package/dist/subpaths/utils/easeInOutQuart.js +1 -2
- package/dist/subpaths/utils/easeInOutQuint.js +1 -2
- package/dist/subpaths/utils/easeInOutSine.js +1 -2
- package/dist/subpaths/utils/easeInQuad.js +1 -2
- package/dist/subpaths/utils/easeInQuart.js +1 -2
- package/dist/subpaths/utils/easeInQuint.js +1 -2
- package/dist/subpaths/utils/easeInSine.js +1 -2
- package/dist/subpaths/utils/easeLinear.js +1 -2
- package/dist/subpaths/utils/easeOutCirc.js +1 -2
- package/dist/subpaths/utils/easeOutCubic.js +1 -2
- package/dist/subpaths/utils/easeOutExpo.js +1 -2
- package/dist/subpaths/utils/easeOutQuad.js +1 -2
- package/dist/subpaths/utils/easeOutQuart.js +1 -2
- package/dist/subpaths/utils/easeOutQuint.js +1 -2
- package/dist/subpaths/utils/easeOutSine.js +1 -2
- package/dist/subpaths/utils/enterTransition.js +1 -2
- package/dist/subpaths/utils/fold.js +1 -2
- package/dist/subpaths/utils/getOffsetSizes.js +1 -2
- package/dist/subpaths/utils/historyPush.js +1 -2
- package/dist/subpaths/utils/historyReplace.js +1 -2
- package/dist/subpaths/utils/inertiaDecay.js +1 -2
- package/dist/subpaths/utils/inertiaFinalValue.js +1 -2
- package/dist/subpaths/utils/inertiaStep.js +1 -2
- package/dist/subpaths/utils/inertiaTimeConstant.js +1 -2
- package/dist/subpaths/utils/isBoolean.js +1 -2
- package/dist/subpaths/utils/isDefined.js +1 -2
- package/dist/subpaths/utils/isFunction.js +1 -2
- package/dist/subpaths/utils/isNull.js +1 -2
- package/dist/subpaths/utils/isNumber.js +1 -2
- package/dist/subpaths/utils/isObject.js +1 -2
- package/dist/subpaths/utils/isString.js +1 -2
- package/dist/subpaths/utils/kebabCase.js +1 -2
- package/dist/subpaths/utils/leaveTransition.js +1 -2
- package/dist/subpaths/utils/lerp.js +1 -2
- package/dist/subpaths/utils/loadImage.js +1 -2
- package/dist/subpaths/utils/loadLink.js +1 -2
- package/dist/subpaths/utils/loadScript.js +1 -2
- package/dist/subpaths/utils/lockScroll.js +1 -2
- package/dist/subpaths/utils/lowerCase.js +1 -2
- package/dist/subpaths/utils/map.js +1 -2
- package/dist/subpaths/utils/matrix.js +1 -2
- package/dist/subpaths/utils/mean.js +1 -2
- package/dist/subpaths/utils/memo.js +1 -2
- package/dist/subpaths/utils/noop.js +1 -2
- package/dist/subpaths/utils/noopValue.js +1 -2
- package/dist/subpaths/utils/objectToURLSearchParams.js +1 -2
- package/dist/subpaths/utils/pascalCase.js +1 -2
- package/dist/subpaths/utils/random.js +1 -2
- package/dist/subpaths/utils/randomInt.js +1 -2
- package/dist/subpaths/utils/randomItem.js +1 -2
- package/dist/subpaths/utils/round.js +1 -2
- package/dist/subpaths/utils/saveActiveElement.js +1 -2
- package/dist/subpaths/utils/scrollPosition.js +1 -2
- package/dist/subpaths/utils/scrollTo.js +1 -2
- package/dist/subpaths/utils/selectorFor.js +1 -2
- package/dist/subpaths/utils/setClassesOrStyles.js +1 -2
- package/dist/subpaths/utils/smoothTo.js +1 -2
- package/dist/subpaths/utils/snakeCase.js +1 -2
- package/dist/subpaths/utils/spring.js +1 -2
- package/dist/subpaths/utils/throttle.js +1 -2
- package/dist/subpaths/utils/transform.js +1 -2
- package/dist/subpaths/utils/transition.js +1 -2
- package/dist/subpaths/utils/trapFocus.js +1 -2
- package/dist/subpaths/utils/untrapFocus.js +1 -2
- package/dist/subpaths/utils/upperCase.js +1 -2
- package/dist/subpaths/utils/wait.js +1 -2
- package/dist/subpaths/utils/withLeadingCharacters.js +1 -2
- package/dist/subpaths/utils/withLeadingSlash.js +1 -2
- package/dist/subpaths/utils/withTrailingCharacters.js +1 -2
- package/dist/subpaths/utils/withTrailingSlash.js +1 -2
- package/dist/subpaths/utils/withoutLeadingCharacters.js +1 -2
- package/dist/subpaths/utils/withoutLeadingCharactersRecursive.js +1 -2
- package/dist/subpaths/utils/withoutLeadingSlash.js +1 -2
- package/dist/subpaths/utils/withoutTrailingCharacters.js +1 -2
- package/dist/subpaths/utils/withoutTrailingCharactersRecursive.js +1 -2
- package/dist/subpaths/utils/withoutTrailingSlash.js +1 -2
- package/dist/subpaths/utils/wrap.js +1 -2
- package/dist/subpaths/viewTransition.js +1 -2
- package/dist/subpaths/warn.js +1 -2
- package/dist/subpaths/watchAttributeNamespace.js +1 -2
- package/dist/subpaths/watchAttributes.js +1 -2
- package/dist/subpaths/whenDOMSettled.js +1 -2
- package/dist/subpaths/withDrag.js +1 -2
- package/dist/subpaths/withInView.js +1 -2
- package/dist/subpaths/withKey.js +1 -2
- package/dist/subpaths/withMutation.js +1 -2
- package/dist/subpaths/withPointer.js +1 -2
- package/dist/subpaths/withRaf.js +1 -2
- package/dist/subpaths/withResize.js +1 -2
- package/dist/subpaths/withScroll.js +1 -2
- package/dist/subpaths/withScrollProgress.js +1 -2
- package/dist/subpaths/write.js +1 -2
- package/dist/swap.d.ts +0 -2
- package/dist/swap.js +1 -2
- package/dist/test/index.d.ts +0 -2
- package/dist/test/index.js +1 -2
- package/dist/utils/deepmerge.d.ts +0 -2
- package/dist/utils/deepmerge.js +1 -2
- package/dist/utils/dom.d.ts +0 -2
- package/dist/utils/dom.js +1 -2
- package/dist/utils/easings.d.ts +0 -2
- package/dist/utils/easings.js +1 -2
- package/dist/utils/focus.d.ts +0 -2
- package/dist/utils/focus.js +1 -2
- package/dist/utils/history.d.ts +0 -2
- package/dist/utils/history.js +1 -2
- package/dist/utils/is.d.ts +0 -2
- package/dist/utils/is.js +1 -2
- package/dist/utils/load.d.ts +0 -2
- package/dist/utils/load.js +1 -2
- package/dist/utils/maths.d.ts +0 -2
- package/dist/utils/maths.js +1 -2
- package/dist/utils/memo.d.ts +0 -2
- package/dist/utils/memo.js +1 -2
- package/dist/utils/noop.d.ts +0 -2
- package/dist/utils/noop.js +1 -2
- package/dist/utils/random.d.ts +0 -2
- package/dist/utils/random.js +1 -2
- package/dist/utils/scroll-lock.d.ts +0 -2
- package/dist/utils/scroll-lock.js +1 -2
- package/dist/utils/scrollTo.d.ts +0 -2
- package/dist/utils/scrollTo.js +1 -2
- package/dist/utils/selectors.d.ts +0 -2
- package/dist/utils/selectors.js +1 -2
- package/dist/utils/smoothTo.d.ts +0 -2
- package/dist/utils/smoothTo.js +1 -2
- package/dist/utils/strings.d.ts +0 -2
- package/dist/utils/strings.js +1 -2
- package/dist/utils/timing.d.ts +0 -2
- package/dist/utils/timing.js +1 -2
- package/dist/utils/transform.d.ts +0 -2
- package/dist/utils/transform.js +1 -2
- package/dist/utils/transition.d.ts +0 -2
- package/dist/utils/transition.js +1 -2
- package/dist/viewTransition.d.ts +0 -2
- package/dist/viewTransition.js +1 -2
- package/package.json +6 -3
- package/skills/studiometa-js-toolkit/SKILL.md +87 -0
- package/skills/studiometa-js-toolkit/references/api/configuration.md +169 -0
- package/skills/studiometa-js-toolkit/references/api/context/createContext.md +46 -0
- package/skills/studiometa-js-toolkit/references/api/context/createGroup.md +67 -0
- package/skills/studiometa-js-toolkit/references/api/context/index.md +69 -0
- package/skills/studiometa-js-toolkit/references/api/context/injectContext.md +58 -0
- package/skills/studiometa-js-toolkit/references/api/context/injectContextSync.md +44 -0
- package/skills/studiometa-js-toolkit/references/api/context/provideContext.md +61 -0
- package/skills/studiometa-js-toolkit/references/api/context/provideRootContext.md +42 -0
- package/skills/studiometa-js-toolkit/references/api/context/signal.md +85 -0
- package/skills/studiometa-js-toolkit/references/api/context/subscribeContext.md +71 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/children.md +92 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/component.md +75 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/index.md +41 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/inject.md +73 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/on.md +149 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/provide.md +77 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/read-write.md +93 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/DIAGNOSTICS.md +137 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/EVENTS.md +45 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/index.md +58 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/reportDiagnostic.md +67 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/warn.md +54 -0
- package/skills/studiometa-js-toolkit/references/api/dom/breakpoints.md +81 -0
- package/skills/studiometa-js-toolkit/references/api/dom/domUpdate.md +70 -0
- package/skills/studiometa-js-toolkit/references/api/dom/emitExtendable.md +68 -0
- package/skills/studiometa-js-toolkit/references/api/dom/index.md +26 -0
- package/skills/studiometa-js-toolkit/references/api/dom/swap.md +105 -0
- package/skills/studiometa-js-toolkit/references/api/dom/watchAttributeNamespace.md +96 -0
- package/skills/studiometa-js-toolkit/references/api/dom/watchAttributes.md +56 -0
- package/skills/studiometa-js-toolkit/references/api/dom/whenDOMSettled.md +41 -0
- package/skills/studiometa-js-toolkit/references/api/html/data-component.md +105 -0
- package/skills/studiometa-js-toolkit/references/api/html/data-mount.md +69 -0
- package/skills/studiometa-js-toolkit/references/api/html/data-option.md +106 -0
- package/skills/studiometa-js-toolkit/references/api/html/data-ref.md +63 -0
- package/skills/studiometa-js-toolkit/references/api/html/index.md +32 -0
- package/skills/studiometa-js-toolkit/references/api/index.md +73 -0
- package/skills/studiometa-js-toolkit/references/api/instance-events.md +75 -0
- package/skills/studiometa-js-toolkit/references/api/instance-methods.md +267 -0
- package/skills/studiometa-js-toolkit/references/api/instance-properties.md +90 -0
- package/skills/studiometa-js-toolkit/references/api/methods-hooks-events.md +149 -0
- package/skills/studiometa-js-toolkit/references/api/methods-hooks-lifecycle.md +90 -0
- package/skills/studiometa-js-toolkit/references/api/methods-hooks-options.md +96 -0
- package/skills/studiometa-js-toolkit/references/api/methods-hooks-services.md +164 -0
- package/skills/studiometa-js-toolkit/references/api/registry/defineManifest.md +57 -0
- package/skills/studiometa-js-toolkit/references/api/registry/fromMetaGlob.md +33 -0
- package/skills/studiometa-js-toolkit/references/api/registry/fromWebpackContext.md +37 -0
- package/skills/studiometa-js-toolkit/references/api/registry/getInstance.md +52 -0
- package/skills/studiometa-js-toolkit/references/api/registry/getInstances.md +48 -0
- package/skills/studiometa-js-toolkit/references/api/registry/getMountedInstances.md +39 -0
- package/skills/studiometa-js-toolkit/references/api/registry/getUnmountedInstances.md +46 -0
- package/skills/studiometa-js-toolkit/references/api/registry/index.md +49 -0
- package/skills/studiometa-js-toolkit/references/api/registry/registerComponent.md +93 -0
- package/skills/studiometa-js-toolkit/references/api/registry/registerComponents.md +37 -0
- package/skills/studiometa-js-toolkit/references/api/registry/registerManifest.md +72 -0
- package/skills/studiometa-js-toolkit/references/api/scheduler/defaultScheduler.md +104 -0
- package/skills/studiometa-js-toolkit/references/api/scheduler/index.md +27 -0
- package/skills/studiometa-js-toolkit/references/api/scheduler/nextFrame.md +31 -0
- package/skills/studiometa-js-toolkit/references/api/scheduler/viewTransition.md +53 -0
- package/skills/studiometa-js-toolkit/references/api/services/createService.md +95 -0
- package/skills/studiometa-js-toolkit/references/api/services/createServiceMixin.md +81 -0
- package/skills/studiometa-js-toolkit/references/api/services/index.md +94 -0
- package/skills/studiometa-js-toolkit/references/api/services/mixins.md +148 -0
- package/skills/studiometa-js-toolkit/references/api/services/perTarget.md +65 -0
- package/skills/studiometa-js-toolkit/references/api/services/toggle.md +80 -0
- package/skills/studiometa-js-toolkit/references/api/services/until.md +44 -0
- package/skills/studiometa-js-toolkit/references/api/services/useBreakpoint.md +42 -0
- package/skills/studiometa-js-toolkit/references/api/services/useDrag.md +119 -0
- package/skills/studiometa-js-toolkit/references/api/services/useInView.md +64 -0
- package/skills/studiometa-js-toolkit/references/api/services/useKey.md +105 -0
- package/skills/studiometa-js-toolkit/references/api/services/useMediaQuery.md +45 -0
- package/skills/studiometa-js-toolkit/references/api/services/useMutation.md +69 -0
- package/skills/studiometa-js-toolkit/references/api/services/usePointer.md +91 -0
- package/skills/studiometa-js-toolkit/references/api/services/usePrefersReducedMotion.md +42 -0
- package/skills/studiometa-js-toolkit/references/api/services/useRaf.md +91 -0
- package/skills/studiometa-js-toolkit/references/api/services/useResize.md +60 -0
- package/skills/studiometa-js-toolkit/references/api/services/useScroll.md +88 -0
- package/skills/studiometa-js-toolkit/references/api/services/useScrollProgress.md +88 -0
- package/skills/studiometa-js-toolkit/references/api/services/useWindowScroll.md +25 -0
- package/skills/studiometa-js-toolkit/references/api/services/useWindowSize.md +25 -0
- package/skills/studiometa-js-toolkit/references/api/storage/createStorage.md +126 -0
- package/skills/studiometa-js-toolkit/references/api/storage/index.md +33 -0
- package/skills/studiometa-js-toolkit/references/api/storage/presets.md +58 -0
- package/skills/studiometa-js-toolkit/references/api/storage/providers.md +109 -0
- package/skills/studiometa-js-toolkit/references/api/test/index.md +214 -0
- package/skills/studiometa-js-toolkit/references/guide/concepts/attribute-grammar.md +93 -0
- package/skills/studiometa-js-toolkit/references/guide/concepts/mutation-engine.md +71 -0
- package/skills/studiometa-js-toolkit/references/guide/concepts/philosophy.md +78 -0
- package/skills/studiometa-js-toolkit/references/guide/concepts/the-registry.md +110 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/autoloading.md +104 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/handling-diagnostics.md +104 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/mount-strategies.md +95 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/scheduling-work.md +124 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/sharing-state.md +218 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/swapping-content.md +92 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/testing-components.md +137 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/typing-components.md +190 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/using-decorators.md +168 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/using-storage.md +125 -0
- package/skills/studiometa-js-toolkit/references/guide/index.md +163 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/installation.md +144 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/lifecycle-hooks.md +174 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/managing-components.md +229 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/managing-options.md +235 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/managing-refs.md +174 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/using-services.md +218 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/working-with-events.md +251 -0
- package/skills/studiometa-js-toolkit/references/guide/migration/v3-to-v4.md +373 -0
- package/skills/studiometa-js-toolkit/references/utils/css.md +98 -0
- package/skills/studiometa-js-toolkit/references/utils/dom.md +54 -0
- package/skills/studiometa-js-toolkit/references/utils/easings.md +217 -0
- package/skills/studiometa-js-toolkit/references/utils/focus.md +84 -0
- package/skills/studiometa-js-toolkit/references/utils/history.md +69 -0
- package/skills/studiometa-js-toolkit/references/utils/index.md +53 -0
- package/skills/studiometa-js-toolkit/references/utils/is.md +84 -0
- package/skills/studiometa-js-toolkit/references/utils/load.md +59 -0
- package/skills/studiometa-js-toolkit/references/utils/math.md +129 -0
- package/skills/studiometa-js-toolkit/references/utils/motion.md +218 -0
- package/skills/studiometa-js-toolkit/references/utils/objects.md +68 -0
- package/skills/studiometa-js-toolkit/references/utils/scroll.md +128 -0
- package/skills/studiometa-js-toolkit/references/utils/strings.md +176 -0
- package/skills/studiometa-js-toolkit/references/utils/timing.md +111 -0
- package/skills/studiometa-js-toolkit/references/utils/transitions.md +122 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
`static config` declares everything the framework needs to know about a component before an instance exists.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
interface BaseConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
components?: Record<string, BaseConstructor | ComponentImporter>;
|
|
9
|
+
refs?: string[];
|
|
10
|
+
options?: Record<string, OptionDefinition>;
|
|
11
|
+
mountStrategy?: MountStrategy;
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## `config.name`
|
|
16
|
+
|
|
17
|
+
**Required.** The name the registry registers under, the token `data-component` writes, and the prefix of every instance's [`$id`](instance-properties.md#id).
|
|
18
|
+
|
|
19
|
+
The name comes from the **merged** config, so a subclass that extends a component and forgets to rename registers under the name it inherited — and collides — rather than under `undefined`.
|
|
20
|
+
|
|
21
|
+
## `config.refs`
|
|
22
|
+
|
|
23
|
+
The refs the component declares. A list ref keeps its `[]`:
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
import { Base } from '@studiometa/js-toolkit';
|
|
27
|
+
|
|
28
|
+
class Tabs extends Base {
|
|
29
|
+
static config = {
|
|
30
|
+
name: 'Tabs',
|
|
31
|
+
refs: ['list', 'tabs[]', 'panels[]'],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
See [Refs](../guide/introduction/managing-refs.md) and [`data-ref`](html/data-ref.md).
|
|
37
|
+
|
|
38
|
+
## `config.options`
|
|
39
|
+
|
|
40
|
+
Each entry is a type, a tuple of types, or an object with `type` and `default`:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
import { Base } from '@studiometa/js-toolkit';
|
|
44
|
+
|
|
45
|
+
class Slider extends Base {
|
|
46
|
+
static config = {
|
|
47
|
+
name: 'Slider',
|
|
48
|
+
options: {
|
|
49
|
+
label: String, // short form
|
|
50
|
+
speed: { type: Number, default: 1 }, // primitive default
|
|
51
|
+
loop: { type: Boolean, default: true },
|
|
52
|
+
tween: { type: Object, default: () => ({}) }, // factory required
|
|
53
|
+
offset: [Number, Array], // a union, in order
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The five option types are `String`, `Number`, `Boolean`, `Array` and `Object`. `Function` is not one, which is what makes a function `default` unambiguously a factory.
|
|
60
|
+
|
|
61
|
+
See [Options](../guide/introduction/managing-options.md) and [`data-option-<name>`](html/data-option.md).
|
|
62
|
+
|
|
63
|
+
## `config.components`
|
|
64
|
+
|
|
65
|
+
The declared **family**. It does two jobs, and neither is ownership:
|
|
66
|
+
|
|
67
|
+
1. it registers those names when this component registers, so one `registerComponent()` call covers a whole tree;
|
|
68
|
+
2. it gives the name set that `on<Child><Event>` resolution needs.
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
static config = {
|
|
72
|
+
name: 'Accordion',
|
|
73
|
+
components: {
|
|
74
|
+
AccordionItem, // a class
|
|
75
|
+
Icon: () => import('./Icon.js'), // a thunk — its own chunk
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- **The key supplies the name**, so a lazy child is a name the registry knows with nothing downloaded.
|
|
81
|
+
- A thunk is deferred rather than resolved, and becomes a lazy entry of the same registry.
|
|
82
|
+
- **First wins, quietly.** Several parents declaring the same lazy child is the normal case.
|
|
83
|
+
- A value written with `class` that does not extend `Base` is reported as `component.invalid-family-declaration`, where it is declared.
|
|
84
|
+
|
|
85
|
+
See [Autoloading](../guide/going-further/autoloading.md).
|
|
86
|
+
|
|
87
|
+
## `config.mountStrategy`
|
|
88
|
+
|
|
89
|
+
The component's default answer to _when_. Any element overrides it with `data-mount`:
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
import { Base } from '@studiometa/js-toolkit';
|
|
93
|
+
|
|
94
|
+
class Map extends Base {
|
|
95
|
+
static config = {
|
|
96
|
+
name: 'Map',
|
|
97
|
+
mountStrategy: 'visible',
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
See [Mount strategies](../guide/going-further/mount-strategies.md) and [`data-mount`](html/data-mount.md).
|
|
103
|
+
|
|
104
|
+
## Merging along the prototype chain
|
|
105
|
+
|
|
106
|
+
`$config` walks the prototype chain and merges every config it finds:
|
|
107
|
+
|
|
108
|
+
| Key | Merge rule |
|
|
109
|
+
| --------------- | --------------------------- |
|
|
110
|
+
| `refs` | union |
|
|
111
|
+
| `options` | entry by entry |
|
|
112
|
+
| `components` | entry by entry |
|
|
113
|
+
| `name` | the most derived class wins |
|
|
114
|
+
| `mountStrategy` | the most derived class wins |
|
|
115
|
+
|
|
116
|
+
A subclass that states a `components` key again wins for **that key only**.
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
import { Base } from '@studiometa/js-toolkit';
|
|
120
|
+
|
|
121
|
+
class AbstractControl extends Base {
|
|
122
|
+
static config = {
|
|
123
|
+
name: 'AbstractControl',
|
|
124
|
+
refs: ['button'],
|
|
125
|
+
options: { label: String },
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
class NavigationControl extends AbstractControl {
|
|
130
|
+
static config = {
|
|
131
|
+
name: 'NavigationControl',
|
|
132
|
+
refs: ['compass'], // merged: ['button', 'compass']
|
|
133
|
+
options: { showCompass: Boolean }, // merged with `label`
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
An intermediate class should declare `static config: BaseConfig`, or let TypeScript infer a literal type every subclass matches.
|
|
139
|
+
|
|
140
|
+
**The registry reads the merged config too**, before any instance exists, through `resolveConfig()`. That is how it knows the mount strategy of a pair, the family to register, and the name a class registers under.
|
|
141
|
+
|
|
142
|
+
## There is no `withExtraConfig()`
|
|
143
|
+
|
|
144
|
+
To extend a component with a different config, declare a class. To extend one you cannot edit, do it in expression position:
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
registerComponent(
|
|
148
|
+
class extends Vendor {
|
|
149
|
+
static config = { name: 'CompactVendor', options: { compact: Boolean } };
|
|
150
|
+
},
|
|
151
|
+
);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## `@component()`
|
|
155
|
+
|
|
156
|
+
The decorator writes `static config` and calls `registerComponent()` in one step, and the two forms merge:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import { Base, component } from '@studiometa/js-toolkit';
|
|
160
|
+
|
|
161
|
+
@component({ name: 'Slider', refs: ['next'] })
|
|
162
|
+
class Slider extends Base {
|
|
163
|
+
static config = { name: 'Slider', options: { speed: Number } };
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
They merge in a class initializer, which runs after the fields and inside the class definition, so `registerComponent()` reads the finished config. A key both sides declare differently is reported as `component.config-conflict`.
|
|
168
|
+
|
|
169
|
+
See [`@component`](decorators/component.md).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# createContext
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
createContext<T = unknown>(description?: string): ContextKey<T>
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Creates a typed injection key.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { createContext, type Signal } from '@studiometa/js-toolkit';
|
|
13
|
+
|
|
14
|
+
interface SliderApi {
|
|
15
|
+
state: Signal<{ index: number }>;
|
|
16
|
+
goNext(): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const SliderContext = createContext<SliderApi>('slider');
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Parameters**
|
|
23
|
+
|
|
24
|
+
- `description` (`string`, optional) — for debugging only.
|
|
25
|
+
|
|
26
|
+
**Return value**
|
|
27
|
+
|
|
28
|
+
- `ContextKey<T>` — an opaque value carrying the phantom type `T`.
|
|
29
|
+
|
|
30
|
+
## Why a value and not a string
|
|
31
|
+
|
|
32
|
+
**The identity of the key is what resolves.** Two keys with the same description are two different keys, so nothing collides — and the type parameter is what makes `$inject(key)` give a typed value with no cast at the call site.
|
|
33
|
+
|
|
34
|
+
Declare the key beside the interface it carries, and export both:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
// slider-context.ts
|
|
38
|
+
export interface SliderApi { … }
|
|
39
|
+
export const SliderContext = createContext<SliderApi>('slider');
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Provider and consumer then import one module and agree by construction.
|
|
43
|
+
|
|
44
|
+
## The default is `unknown`
|
|
45
|
+
|
|
46
|
+
`createContext('name')` with no type parameter gives `ContextKey<unknown>`, so `$inject()` resolves with `unknown` and the consumer has to narrow. Give it the type.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# createGroup
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
createGroup<T extends GroupMember = GroupMember>(): Group<T>
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
A membership set whose members list is a reactive value.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
interface Group<T extends GroupMember = GroupMember> {
|
|
11
|
+
readonly members: Signal<readonly T[]>;
|
|
12
|
+
join(member: T): () => void;
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
A `GroupMember` is anything with a `readonly $el: Element` — which every `Base` instance is.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
The coordinator owns the membership and gives out the ways in:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { Base, createContext, createGroup, type Signal } from '@studiometa/js-toolkit';
|
|
24
|
+
|
|
25
|
+
interface GroupApi {
|
|
26
|
+
members: Signal<readonly Base[]>;
|
|
27
|
+
join(peer: Base): () => void;
|
|
28
|
+
open(peer: Base): void;
|
|
29
|
+
}
|
|
30
|
+
const DisclosureGroupContext = createContext<GroupApi>('disclosure-group');
|
|
31
|
+
class DisclosureGroup extends Base {
|
|
32
|
+
static config = { name: 'DisclosureGroup' };
|
|
33
|
+
|
|
34
|
+
#peers = createGroup<Base>();
|
|
35
|
+
|
|
36
|
+
api = this.$provide(DisclosureGroupContext, {
|
|
37
|
+
members: this.#peers.members, // the members to read, in document order
|
|
38
|
+
join: (peer: Base) => this.#peers.join(peer), // returns the leave function
|
|
39
|
+
open: (peer: Base) => this.open(peer), // the invariant stays here
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
mounted() {
|
|
43
|
+
// The membership is a value: re-check the invariant on each change.
|
|
44
|
+
return this.#peers.members.subscribe((members) => this.enforce(members));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
open(peer: Base) {}
|
|
48
|
+
|
|
49
|
+
enforce(members: readonly Base[]) {}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A member joins the nearest group whenever that group appears — see [`subscribeContext()`](subscribeContext.md).
|
|
54
|
+
|
|
55
|
+
## What it does, and what it does not
|
|
56
|
+
|
|
57
|
+
- **`join()` returns its own `leave`**, so a member that moves to a nearer group leaves the old one first.
|
|
58
|
+
- **The membership is a value.** A coordinator subscribes to it and re-checks its invariant on each change, rather than being called back on a mutation.
|
|
59
|
+
- **Document order is the tie-breaker**, so the markup decides which peer keeps its state.
|
|
60
|
+
- **Nothing sweeps disconnected members.** The teardown of the member removes it.
|
|
61
|
+
- **It names no group and resolves no scope.** Scope comes from nearest-provider-wins, so a nested group takes its own members only.
|
|
62
|
+
|
|
63
|
+
The helper holds a `Set` and a [`Signal`](signal.md), and nothing else. That is the whole implementation.
|
|
64
|
+
|
|
65
|
+
## It replaces `withGroup`
|
|
66
|
+
|
|
67
|
+
`withGroup` is not ported. A group is a provided value now, so its scope is the provider's subtree rather than a name in a global table — and a nested group is a nested provider, with nothing to configure.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Shared state
|
|
2
|
+
|
|
3
|
+
provide/inject in core, with the shape of Vue and the mechanics of the WICG context protocol.
|
|
4
|
+
|
|
5
|
+
## The functions
|
|
6
|
+
|
|
7
|
+
| Function | Does |
|
|
8
|
+
| -------------------------------------------------------------- | --------------------------------------------- |
|
|
9
|
+
| [`createContext(description?)`](createContext.md) | a typed key |
|
|
10
|
+
| [`signal(initialValue)`](signal.md) | a reactive value |
|
|
11
|
+
| [`provideContext(el, key, value)`](provideContext.md) | provide on an element |
|
|
12
|
+
| [`provideRootContext(key, create)`](provideRootContext.md) | provide page-wide, created at most once |
|
|
13
|
+
| [`injectContext(el, key)`](injectContext.md) | a promise for the nearest value |
|
|
14
|
+
| [`injectContextSync(el, key)`](injectContextSync.md) | the nearest value, or `undefined` |
|
|
15
|
+
| [`subscribeContext(el, key, cb)`](subscribeContext.md) | every answer, as providers come and go |
|
|
16
|
+
| [`createGroup()`](createGroup.md) | a membership set with a reactive members list |
|
|
17
|
+
|
|
18
|
+
From inside a component, `$provide()`, `$inject()` and `$injectSync()` are the same three, with the element filled in. The [`@provide`](../decorators/provide.md) and [`@inject`](../decorators/inject.md) decorators are field sugar over them.
|
|
19
|
+
|
|
20
|
+
## The model
|
|
21
|
+
|
|
22
|
+
- **The injection key is typed**, so strings cannot collide.
|
|
23
|
+
- **The scope is the subtree**, and the nearest provider wins.
|
|
24
|
+
- **The value is provided as it is.** Nothing is wrapped, so the type of the key is the contract from end to end. A reactive value is a provided `Signal`. A command surface is a provided object.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { Base, createContext, signal, type Signal } from '@studiometa/js-toolkit';
|
|
28
|
+
|
|
29
|
+
interface SliderApi {
|
|
30
|
+
state: Signal<{ index: number; total: number }>;
|
|
31
|
+
goNext(): void;
|
|
32
|
+
}
|
|
33
|
+
const SliderContext = createContext<SliderApi>('slider');
|
|
34
|
+
class Slider extends Base {
|
|
35
|
+
static config = { name: 'Slider' };
|
|
36
|
+
|
|
37
|
+
api = this.$provide(SliderContext, {
|
|
38
|
+
state: signal({ index: 0, total: 0 }), // what changes
|
|
39
|
+
goNext: () => {}, // what a control can command
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Two ways to ask
|
|
45
|
+
|
|
46
|
+
| Form | Resolves | When nothing provides |
|
|
47
|
+
| ------------------ | --------------------------------- | ----------------------------------------------------- |
|
|
48
|
+
| `$inject(key)` | a promise, awaited in `mounted()` | it never settles: a missing provider means "not yet". |
|
|
49
|
+
| `$injectSync(key)` | the value, synchronously | `undefined`: the caller falls back or does nothing. |
|
|
50
|
+
|
|
51
|
+
The pending request of the async form is **unmount-scoped**. A new mount runs `mounted()` again and asks again. The `@inject` field decorator asks once, at construction; a consumer that can wait through several cycles calls `$inject()` from `mounted()`.
|
|
52
|
+
|
|
53
|
+
## The mechanics
|
|
54
|
+
|
|
55
|
+
The consumer dispatches a bubbling, **module-private** `js-toolkit:context:request` event carrying a key, a callback and a subscription marker. It is deliberately not part of public `EVENTS`.
|
|
56
|
+
|
|
57
|
+
The nearest **mounted** provider answers and stops propagation. `provideContext()` replays the requests that have no first answer yet, which is what makes mount order irrelevant. `injectContext()` and `$inject()` are one-shot.
|
|
58
|
+
|
|
59
|
+
Duplicate bundles share the basic provider and pending-request state through the `context` shared-runtime slot at schema revision 2. The optional owner map, weak index and listener flag use the `context-subscription` slot at revision 1 — and `context.ts` and the `Base` graph import none of that optional state.
|
|
60
|
+
|
|
61
|
+
## Scopes
|
|
62
|
+
|
|
63
|
+
`$provide()` in a field initializer is **instance-scoped**: it is never released and dies with the element. A component whose declaration is withdrawn keeps providing until its element goes.
|
|
64
|
+
|
|
65
|
+
A **root** provider cannot be disposed and it outlives the instance that asked first, because it is page state. `withGroup` is not ported.
|
|
66
|
+
|
|
67
|
+
## Read next
|
|
68
|
+
|
|
69
|
+
[Shared state](../../guide/going-further/sharing-state.md) walks the whole pattern, from a coordinator's provided API to a member joining the nearest group.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# injectContext
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
injectContext<T>(el: Element, key: ContextKey<T>): { promise: Promise<T>; cancel: () => void }
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Asks the nearest provider for a value, once.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { createContext, injectContext } from '@studiometa/js-toolkit';
|
|
13
|
+
|
|
14
|
+
const Key = createContext<number>('answer');
|
|
15
|
+
const el = document.body;
|
|
16
|
+
const { promise, cancel } = injectContext(el, Key);
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Return value**
|
|
20
|
+
|
|
21
|
+
- `promise` — resolves with the nearest provided value.
|
|
22
|
+
- `cancel` — withdraws the request.
|
|
23
|
+
|
|
24
|
+
## It never settles when nothing provides
|
|
25
|
+
|
|
26
|
+
**A missing provider means "not yet", not "no".** The request stays pending, and it resolves when a provider appears and replays it — which is what makes mount order irrelevant.
|
|
27
|
+
|
|
28
|
+
If you need an answer now, or none, use [`injectContextSync()`](injectContextSync.md).
|
|
29
|
+
|
|
30
|
+
## From a component
|
|
31
|
+
|
|
32
|
+
`$inject()` is the same call with the element filled in, and it returns the promise directly:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { Base, createContext, type Signal } from '@studiometa/js-toolkit';
|
|
36
|
+
|
|
37
|
+
const CountContext = createContext<Signal<number>>('count');
|
|
38
|
+
class Output extends Base {
|
|
39
|
+
static config = { name: 'Output' };
|
|
40
|
+
|
|
41
|
+
async mounted() {
|
|
42
|
+
const count = await this.$inject(CountContext);
|
|
43
|
+
return count.subscribe((value) => {
|
|
44
|
+
this.$el.textContent = String(value);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**The pending request is unmount-scoped**
|
|
51
|
+
|
|
52
|
+
`$unmount()` cancels it, and a new mount runs `mounted()` again and asks again. That is why `mounted()` is the right place: a component that outlives several cycles asks once per cycle, and never holds a request for a scope it has left.
|
|
53
|
+
|
|
54
|
+
The [`@inject`](../decorators/inject.md) field decorator asks once, at construction, instead.
|
|
55
|
+
|
|
56
|
+
## It is one-shot
|
|
57
|
+
|
|
58
|
+
`injectContext()` and `$inject()` resolve with the **first** answer and stop. To follow providers as they come and go, use [`subscribeContext()`](subscribeContext.md).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# injectContextSync
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
injectContextSync<T>(el: Element, key: ContextKey<T>): T | undefined
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
The nearest provided value, synchronously, or `undefined`.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { createContext, injectContextSync } from '@studiometa/js-toolkit';
|
|
13
|
+
|
|
14
|
+
const Key = createContext<number>('answer');
|
|
15
|
+
const el = document.body;
|
|
16
|
+
const value = injectContextSync(el, Key);
|
|
17
|
+
|
|
18
|
+
if (value === undefined) {
|
|
19
|
+
// no provider — fall back, or do nothing
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## When to reach for it
|
|
24
|
+
|
|
25
|
+
When the answer is **optional and the caller has a fallback**. `undefined` means "no provider right now", which is a different statement from `$inject()`'s "not yet".
|
|
26
|
+
|
|
27
|
+
The canonical pair is a look-up-or-create:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { createContext, injectContextSync, provideRootContext } from '@studiometa/js-toolkit';
|
|
31
|
+
|
|
32
|
+
const DataChannels = createContext<Map<string, unknown>>('channels');
|
|
33
|
+
const el = document.body;
|
|
34
|
+
const channels =
|
|
35
|
+
injectContextSync(el, DataChannels) ?? provideRootContext(DataChannels, () => new Map());
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## From a component
|
|
39
|
+
|
|
40
|
+
`$injectSync(key)` is the same call with the element filled in.
|
|
41
|
+
|
|
42
|
+
**It answers for right now**
|
|
43
|
+
|
|
44
|
+
A provider that mounts later is not seen, because there is no request left pending. If mount order is not something you control, use [`injectContext()`](injectContext.md) or [`subscribeContext()`](subscribeContext.md).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# provideContext
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
provideContext<T>(el: Element, key: ContextKey<T>, value: T): { value: T; dispose: () => void }
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Provides a value to the subtree of `el`.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { createContext, provideContext } from '@studiometa/js-toolkit';
|
|
13
|
+
|
|
14
|
+
const Key = createContext<number>('answer');
|
|
15
|
+
const el = document.body;
|
|
16
|
+
const { value, dispose } = provideContext(el, Key, 42);
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Parameters**
|
|
20
|
+
|
|
21
|
+
- `el` — the element that owns the scope.
|
|
22
|
+
- `key` — a [`ContextKey`](createContext.md).
|
|
23
|
+
- `value` — provided **as it is**. Nothing is wrapped.
|
|
24
|
+
|
|
25
|
+
**Return value**
|
|
26
|
+
|
|
27
|
+
- `value` — the value, so the call can be an expression.
|
|
28
|
+
- `dispose` — stops answering for this key on this element.
|
|
29
|
+
|
|
30
|
+
## From a component
|
|
31
|
+
|
|
32
|
+
`$provide()` is the same call with the element filled in, and it returns the value directly so it reads as a field initializer:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { Base, createContext, signal, type Signal } from '@studiometa/js-toolkit';
|
|
36
|
+
|
|
37
|
+
const CountContext = createContext<Signal<number>>('count');
|
|
38
|
+
class Counter extends Base {
|
|
39
|
+
static config = { name: 'Counter' };
|
|
40
|
+
|
|
41
|
+
count = this.$provide(CountContext, signal(0));
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**`$provide()` is instance-scoped**
|
|
46
|
+
|
|
47
|
+
It is never released, and it dies with the instance or its element. A component whose declaration is withdrawn keeps providing until its element goes — which is why the call belongs in the constructor or a field initializer, not in `mounted()`.
|
|
48
|
+
|
|
49
|
+
## Nearest wins
|
|
50
|
+
|
|
51
|
+
The scope is the subtree, and a nearer provider shadows a further one by answering first and stopping propagation.
|
|
52
|
+
|
|
53
|
+
## It replays pending requests
|
|
54
|
+
|
|
55
|
+
A consumer that asked before any provider existed has a pending request with no first answer. `provideContext()` **replays those requests**, which is what makes mount order irrelevant: a child that mounts before its coordinator still gets its answer when the coordinator arrives.
|
|
56
|
+
|
|
57
|
+
Only a **mounted** provider answers.
|
|
58
|
+
|
|
59
|
+
## Page-wide
|
|
60
|
+
|
|
61
|
+
For state that belongs to the page rather than to a subtree, use [`provideRootContext()`](provideRootContext.md).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# provideRootContext
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
provideRootContext<T>(key: ContextKey<T>, create: () => T): T
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Provides a value on `document.documentElement`, making the page-wide case the **outermost scope of the same mechanism**.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { createContext, injectContextSync, provideRootContext } from '@studiometa/js-toolkit';
|
|
13
|
+
|
|
14
|
+
const DataChannels = createContext<Map<string, unknown>>('channels');
|
|
15
|
+
const el = document.body;
|
|
16
|
+
// Scoped or page-wide, resolved the same way, nearest first.
|
|
17
|
+
const channels =
|
|
18
|
+
injectContextSync(el, DataChannels) ?? provideRootContext(DataChannels, () => new Map());
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Parameters**
|
|
22
|
+
|
|
23
|
+
- `key` — a [`ContextKey`](createContext.md).
|
|
24
|
+
- `create` — a factory, run **at most once per key**.
|
|
25
|
+
|
|
26
|
+
**Return value**
|
|
27
|
+
|
|
28
|
+
- `T` — the value, created or already there.
|
|
29
|
+
|
|
30
|
+
## Why it is the same mechanism
|
|
31
|
+
|
|
32
|
+
Because the value sits on `document.documentElement`, a request from anywhere reaches it by bubbling, and **a nearer provider still wins** through `stopPropagation`. There is no separate global registry and no second lookup path.
|
|
33
|
+
|
|
34
|
+
## Lazy, and once
|
|
35
|
+
|
|
36
|
+
`create` runs at most once per key, and **nothing is created at import time**. A page that never asks for a key never builds its value.
|
|
37
|
+
|
|
38
|
+
## It cannot be disposed
|
|
39
|
+
|
|
40
|
+
A root provider outlives the instance that asked for it first, because it is page state. That is the point: the first component to need a page-wide channel should not own its lifetime.
|
|
41
|
+
|
|
42
|
+
This is what replaces `withGroup`, which is not ported. For a scoped set of peers, use [`createGroup()`](createGroup.md) with an ordinary [`provideContext()`](provideContext.md).
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# signal
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
signal<T>(initialValue: T): Signal<T>
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
A reactive value. The accessor is `.value`.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
interface Signal<T = unknown> {
|
|
11
|
+
value: T;
|
|
12
|
+
subscribe(callback: (value: T) => void, options?: { immediate?: boolean }): () => void;
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { signal } from '@studiometa/js-toolkit';
|
|
20
|
+
|
|
21
|
+
const count = signal(0);
|
|
22
|
+
|
|
23
|
+
const unsubscribe = count.subscribe((value) => console.log(value), { immediate: true });
|
|
24
|
+
|
|
25
|
+
count.value = 1;
|
|
26
|
+
count.value += 1;
|
|
27
|
+
|
|
28
|
+
unsubscribe();
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Parameters**
|
|
32
|
+
|
|
33
|
+
- `initialValue` (`T`).
|
|
34
|
+
|
|
35
|
+
**Return value**
|
|
36
|
+
|
|
37
|
+
- `Signal<T>`. `subscribe()` returns the unsubscribe function.
|
|
38
|
+
|
|
39
|
+
## A write settles synchronously, and the newest value wins
|
|
40
|
+
|
|
41
|
+
The delivery loop re-reads the value after each callback. If the value moved, the loop **abandons the round and starts again on the new value**, so a subscriber that was not reached yet skips the old value entirely.
|
|
42
|
+
|
|
43
|
+
Delivery stays in the same task. There is no batching and no microtask.
|
|
44
|
+
|
|
45
|
+
**A subscriber that writes on every delivery live-locks the loop**
|
|
46
|
+
|
|
47
|
+
Each write restarts the round, so the loop never finishes. Guard the write, or move it out of the subscriber.
|
|
48
|
+
|
|
49
|
+
## It is a factory over a closure
|
|
50
|
+
|
|
51
|
+
There is no class and no proxy. `signal()` closes over the value and a subscriber set, which is why it is the right thing to _provide_: the value crossing a context boundary is the signal itself, and the type of the key says so.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { Base, createContext, signal, type Signal } from '@studiometa/js-toolkit';
|
|
55
|
+
|
|
56
|
+
const CountContext = createContext<Signal<number>>('count');
|
|
57
|
+
class Counter extends Base {
|
|
58
|
+
static config = { name: 'Counter' };
|
|
59
|
+
|
|
60
|
+
count = this.$provide(CountContext, signal(0));
|
|
61
|
+
|
|
62
|
+
increment() {
|
|
63
|
+
this.count.value += 1;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
class CounterOutput extends Base {
|
|
68
|
+
static config = { name: 'CounterOutput' };
|
|
69
|
+
|
|
70
|
+
async mounted() {
|
|
71
|
+
const count = await this.$inject(CountContext);
|
|
72
|
+
return count.subscribe((value) => {
|
|
73
|
+
this.$el.textContent = String(value);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Failures
|
|
80
|
+
|
|
81
|
+
A subscriber that throws is isolated and reported as `callback.signal-failed`, so one subscriber cannot stop the others.
|
|
82
|
+
|
|
83
|
+
## `toggle()` works on it
|
|
84
|
+
|
|
85
|
+
[`toggle(subscribe)`](../services/toggle.md) takes anything that returns its own unsubscribe function, a `Signal` included.
|