@craft-ts/core 0.7.0-beta.13
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/LICENSE +21 -0
- package/package.json +58 -0
- package/src/index.d.ts +148 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +150 -0
- package/src/index.js.map +1 -0
- package/src/lib/after-recomputation.d.ts +327 -0
- package/src/lib/after-recomputation.d.ts.map +1 -0
- package/src/lib/after-recomputation.js +25 -0
- package/src/lib/after-recomputation.js.map +1 -0
- package/src/lib/app-checked-di.d.ts +82 -0
- package/src/lib/app-checked-di.d.ts.map +1 -0
- package/src/lib/app-checked-di.js +1 -0
- package/src/lib/app-checked-di.js.map +1 -0
- package/src/lib/async-process.d.ts +411 -0
- package/src/lib/async-process.d.ts.map +1 -0
- package/src/lib/async-process.js +702 -0
- package/src/lib/async-process.js.map +1 -0
- package/src/lib/branded-component/branded-component.d.ts +129 -0
- package/src/lib/branded-component/branded-component.d.ts.map +1 -0
- package/src/lib/branded-component/branded-component.js +7 -0
- package/src/lib/branded-component/branded-component.js.map +1 -0
- package/src/lib/browser-boundaries.d.ts +165 -0
- package/src/lib/browser-boundaries.d.ts.map +1 -0
- package/src/lib/browser-boundaries.js +550 -0
- package/src/lib/browser-boundaries.js.map +1 -0
- package/src/lib/client-di-requirement.d.ts +28 -0
- package/src/lib/client-di-requirement.d.ts.map +1 -0
- package/src/lib/client-di-requirement.js +11 -0
- package/src/lib/client-di-requirement.js.map +1 -0
- package/src/lib/client-function-middleware.d.ts +130 -0
- package/src/lib/client-function-middleware.d.ts.map +1 -0
- package/src/lib/client-function-middleware.js +144 -0
- package/src/lib/client-function-middleware.js.map +1 -0
- package/src/lib/component-monitoring.d.ts +7 -0
- package/src/lib/component-monitoring.d.ts.map +1 -0
- package/src/lib/component-monitoring.js +28 -0
- package/src/lib/component-monitoring.js.map +1 -0
- package/src/lib/component-register.d.ts +12 -0
- package/src/lib/component-register.d.ts.map +1 -0
- package/src/lib/component-register.js +13 -0
- package/src/lib/component-register.js.map +1 -0
- package/src/lib/computed-source.d.ts +303 -0
- package/src/lib/computed-source.d.ts.map +1 -0
- package/src/lib/computed-source.js +319 -0
- package/src/lib/computed-source.js.map +1 -0
- package/src/lib/correlation-id-plugin.d.ts +3 -0
- package/src/lib/correlation-id-plugin.d.ts.map +1 -0
- package/src/lib/correlation-id-plugin.js +73 -0
- package/src/lib/correlation-id-plugin.js.map +1 -0
- package/src/lib/correlation-id.d.ts +30 -0
- package/src/lib/correlation-id.d.ts.map +1 -0
- package/src/lib/correlation-id.js +86 -0
- package/src/lib/correlation-id.js.map +1 -0
- package/src/lib/craft-a11y.d.ts +22 -0
- package/src/lib/craft-a11y.d.ts.map +1 -0
- package/src/lib/craft-a11y.js +32 -0
- package/src/lib/craft-a11y.js.map +1 -0
- package/src/lib/craft-activated-route.d.ts +21 -0
- package/src/lib/craft-activated-route.d.ts.map +1 -0
- package/src/lib/craft-activated-route.js +20 -0
- package/src/lib/craft-activated-route.js.map +1 -0
- package/src/lib/craft-app-config.d.ts +91 -0
- package/src/lib/craft-app-config.d.ts.map +1 -0
- package/src/lib/craft-app-config.js +64 -0
- package/src/lib/craft-app-config.js.map +1 -0
- package/src/lib/craft-codec.d.ts +16 -0
- package/src/lib/craft-codec.d.ts.map +1 -0
- package/src/lib/craft-codec.js +1 -0
- package/src/lib/craft-codec.js.map +1 -0
- package/src/lib/craft-computed.d.ts +31 -0
- package/src/lib/craft-computed.d.ts.map +1 -0
- package/src/lib/craft-computed.js +81 -0
- package/src/lib/craft-computed.js.map +1 -0
- package/src/lib/craft-control-flow.d.ts +14 -0
- package/src/lib/craft-control-flow.d.ts.map +1 -0
- package/src/lib/craft-control-flow.js +18 -0
- package/src/lib/craft-control-flow.js.map +1 -0
- package/src/lib/craft-effect.d.ts +13 -0
- package/src/lib/craft-effect.d.ts.map +1 -0
- package/src/lib/craft-effect.js +93 -0
- package/src/lib/craft-effect.js.map +1 -0
- package/src/lib/craft-exception.d.ts +40 -0
- package/src/lib/craft-exception.d.ts.map +1 -0
- package/src/lib/craft-exception.js +16 -0
- package/src/lib/craft-exception.js.map +1 -0
- package/src/lib/craft-gen.d.ts +123 -0
- package/src/lib/craft-gen.d.ts.map +1 -0
- package/src/lib/craft-gen.js +90 -0
- package/src/lib/craft-gen.js.map +1 -0
- package/src/lib/craft-generator-runtime.d.ts +110 -0
- package/src/lib/craft-generator-runtime.d.ts.map +1 -0
- package/src/lib/craft-generator-runtime.js +191 -0
- package/src/lib/craft-generator-runtime.js.map +1 -0
- package/src/lib/craft-guard-runtime.d.ts +70 -0
- package/src/lib/craft-guard-runtime.d.ts.map +1 -0
- package/src/lib/craft-guard-runtime.js +195 -0
- package/src/lib/craft-guard-runtime.js.map +1 -0
- package/src/lib/craft-handshake.d.ts +35 -0
- package/src/lib/craft-handshake.d.ts.map +1 -0
- package/src/lib/craft-handshake.js +34 -0
- package/src/lib/craft-handshake.js.map +1 -0
- package/src/lib/craft-http-client.d.ts +236 -0
- package/src/lib/craft-http-client.d.ts.map +1 -0
- package/src/lib/craft-http-client.js +437 -0
- package/src/lib/craft-http-client.js.map +1 -0
- package/src/lib/craft-http-trace.d.ts +12 -0
- package/src/lib/craft-http-trace.d.ts.map +1 -0
- package/src/lib/craft-http-trace.js +28 -0
- package/src/lib/craft-http-trace.js.map +1 -0
- package/src/lib/craft-lazy.d.ts +42 -0
- package/src/lib/craft-lazy.d.ts.map +1 -0
- package/src/lib/craft-lazy.js +83 -0
- package/src/lib/craft-lazy.js.map +1 -0
- package/src/lib/craft-load-retry.d.ts +76 -0
- package/src/lib/craft-load-retry.d.ts.map +1 -0
- package/src/lib/craft-load-retry.js +160 -0
- package/src/lib/craft-load-retry.js.map +1 -0
- package/src/lib/craft-machine-history.d.ts +145 -0
- package/src/lib/craft-machine-history.d.ts.map +1 -0
- package/src/lib/craft-machine-history.js +276 -0
- package/src/lib/craft-machine-history.js.map +1 -0
- package/src/lib/craft-match.d.ts +49 -0
- package/src/lib/craft-match.d.ts.map +1 -0
- package/src/lib/craft-match.js +58 -0
- package/src/lib/craft-match.js.map +1 -0
- package/src/lib/craft-method.d.ts +28 -0
- package/src/lib/craft-method.d.ts.map +1 -0
- package/src/lib/craft-method.js +45 -0
- package/src/lib/craft-method.js.map +1 -0
- package/src/lib/craft-node-directive.d.ts +32 -0
- package/src/lib/craft-node-directive.d.ts.map +1 -0
- package/src/lib/craft-node-directive.js +22 -0
- package/src/lib/craft-node-directive.js.map +1 -0
- package/src/lib/craft-pending.d.ts +115 -0
- package/src/lib/craft-pending.d.ts.map +1 -0
- package/src/lib/craft-pending.js +187 -0
- package/src/lib/craft-pending.js.map +1 -0
- package/src/lib/craft-pipe.d.ts +63 -0
- package/src/lib/craft-pipe.d.ts.map +1 -0
- package/src/lib/craft-pipe.js +57 -0
- package/src/lib/craft-pipe.js.map +1 -0
- package/src/lib/craft-platform.d.ts +50 -0
- package/src/lib/craft-platform.d.ts.map +1 -0
- package/src/lib/craft-platform.js +175 -0
- package/src/lib/craft-platform.js.map +1 -0
- package/src/lib/craft-primitive-gen.d.ts +137 -0
- package/src/lib/craft-primitive-gen.d.ts.map +1 -0
- package/src/lib/craft-primitive-gen.js +76 -0
- package/src/lib/craft-primitive-gen.js.map +1 -0
- package/src/lib/craft-primitive-registry.d.ts +113 -0
- package/src/lib/craft-primitive-registry.d.ts.map +1 -0
- package/src/lib/craft-primitive-registry.js +159 -0
- package/src/lib/craft-primitive-registry.js.map +1 -0
- package/src/lib/craft-program-operators.d.ts +101 -0
- package/src/lib/craft-program-operators.d.ts.map +1 -0
- package/src/lib/craft-program-operators.js +116 -0
- package/src/lib/craft-program-operators.js.map +1 -0
- package/src/lib/craft-program-runtime.d.ts +80 -0
- package/src/lib/craft-program-runtime.d.ts.map +1 -0
- package/src/lib/craft-program-runtime.js +166 -0
- package/src/lib/craft-program-runtime.js.map +1 -0
- package/src/lib/craft-register-for-runtime.d.ts +39 -0
- package/src/lib/craft-register-for-runtime.d.ts.map +1 -0
- package/src/lib/craft-register-for-runtime.js +96 -0
- package/src/lib/craft-register-for-runtime.js.map +1 -0
- package/src/lib/craft-register-for.d.ts +57 -0
- package/src/lib/craft-register-for.d.ts.map +1 -0
- package/src/lib/craft-register-for.js +200 -0
- package/src/lib/craft-register-for.js.map +1 -0
- package/src/lib/craft-render-identity.d.ts +19 -0
- package/src/lib/craft-render-identity.d.ts.map +1 -0
- package/src/lib/craft-render-identity.js +23 -0
- package/src/lib/craft-render-identity.js.map +1 -0
- package/src/lib/craft-replay.d.ts +5 -0
- package/src/lib/craft-replay.d.ts.map +1 -0
- package/src/lib/craft-replay.js +28 -0
- package/src/lib/craft-replay.js.map +1 -0
- package/src/lib/craft-resolve.d.ts +39 -0
- package/src/lib/craft-resolve.d.ts.map +1 -0
- package/src/lib/craft-resolve.js +9 -0
- package/src/lib/craft-resolve.js.map +1 -0
- package/src/lib/craft-resource.d.ts +11 -0
- package/src/lib/craft-resource.d.ts.map +1 -0
- package/src/lib/craft-resource.js +264 -0
- package/src/lib/craft-resource.js.map +1 -0
- package/src/lib/craft-route-exceptions.d.ts +785 -0
- package/src/lib/craft-route-exceptions.d.ts.map +1 -0
- package/src/lib/craft-route-exceptions.js +86 -0
- package/src/lib/craft-route-exceptions.js.map +1 -0
- package/src/lib/craft-route-load-error.d.ts +1145 -0
- package/src/lib/craft-route-load-error.d.ts.map +1 -0
- package/src/lib/craft-route-load-error.js +173 -0
- package/src/lib/craft-route-load-error.js.map +1 -0
- package/src/lib/craft-route-meta.d.ts +52 -0
- package/src/lib/craft-route-meta.d.ts.map +1 -0
- package/src/lib/craft-route-meta.js +16 -0
- package/src/lib/craft-route-meta.js.map +1 -0
- package/src/lib/craft-route-target.d.ts +27 -0
- package/src/lib/craft-route-target.d.ts.map +1 -0
- package/src/lib/craft-route-target.js +22 -0
- package/src/lib/craft-route-target.js.map +1 -0
- package/src/lib/craft-router-outlet.d.ts +105 -0
- package/src/lib/craft-router-outlet.d.ts.map +1 -0
- package/src/lib/craft-router-outlet.js +735 -0
- package/src/lib/craft-router-outlet.js.map +1 -0
- package/src/lib/craft-router-tokens.d.ts +49 -0
- package/src/lib/craft-router-tokens.d.ts.map +1 -0
- package/src/lib/craft-router-tokens.js +15 -0
- package/src/lib/craft-router-tokens.js.map +1 -0
- package/src/lib/craft-router-trace.d.ts +18 -0
- package/src/lib/craft-router-trace.d.ts.map +1 -0
- package/src/lib/craft-router-trace.js +54 -0
- package/src/lib/craft-router-trace.js.map +1 -0
- package/src/lib/craft-router.d.ts +248 -0
- package/src/lib/craft-router.d.ts.map +1 -0
- package/src/lib/craft-router.js +559 -0
- package/src/lib/craft-router.js.map +1 -0
- package/src/lib/craft-routes.d.ts +755 -0
- package/src/lib/craft-routes.d.ts.map +1 -0
- package/src/lib/craft-routes.js +510 -0
- package/src/lib/craft-routes.js.map +1 -0
- package/src/lib/craft-service.d.ts +1034 -0
- package/src/lib/craft-service.d.ts.map +1 -0
- package/src/lib/craft-service.js +1072 -0
- package/src/lib/craft-service.js.map +1 -0
- package/src/lib/craft-service.shared.d.ts +35 -0
- package/src/lib/craft-service.shared.d.ts.map +1 -0
- package/src/lib/craft-service.shared.js +4 -0
- package/src/lib/craft-service.shared.js.map +1 -0
- package/src/lib/craft-settled.d.ts +171 -0
- package/src/lib/craft-settled.d.ts.map +1 -0
- package/src/lib/craft-settled.js +130 -0
- package/src/lib/craft-settled.js.map +1 -0
- package/src/lib/craft-ssr.d.ts +29 -0
- package/src/lib/craft-ssr.d.ts.map +1 -0
- package/src/lib/craft-ssr.js +27 -0
- package/src/lib/craft-ssr.js.map +1 -0
- package/src/lib/craft-state-machine-runtime.d.ts +88 -0
- package/src/lib/craft-state-machine-runtime.d.ts.map +1 -0
- package/src/lib/craft-state-machine-runtime.js +167 -0
- package/src/lib/craft-state-machine-runtime.js.map +1 -0
- package/src/lib/craft-state-machine.d.ts +233 -0
- package/src/lib/craft-state-machine.d.ts.map +1 -0
- package/src/lib/craft-state-machine.js +254 -0
- package/src/lib/craft-state-machine.js.map +1 -0
- package/src/lib/craft-target-runtime.d.ts +20 -0
- package/src/lib/craft-target-runtime.d.ts.map +1 -0
- package/src/lib/craft-target-runtime.js +42 -0
- package/src/lib/craft-target-runtime.js.map +1 -0
- package/src/lib/craft-transfer-snapshot.d.ts +19 -0
- package/src/lib/craft-transfer-snapshot.d.ts.map +1 -0
- package/src/lib/craft-transfer-snapshot.js +90 -0
- package/src/lib/craft-transfer-snapshot.js.map +1 -0
- package/src/lib/craft-unique.d.ts +7 -0
- package/src/lib/craft-unique.d.ts.map +1 -0
- package/src/lib/craft-unique.js +16 -0
- package/src/lib/craft-unique.js.map +1 -0
- package/src/lib/craft-until-settled.d.ts +99 -0
- package/src/lib/craft-until-settled.d.ts.map +1 -0
- package/src/lib/craft-until-settled.js +81 -0
- package/src/lib/craft-until-settled.js.map +1 -0
- package/src/lib/craft-use.d.ts +26 -0
- package/src/lib/craft-use.d.ts.map +1 -0
- package/src/lib/craft-use.js +37 -0
- package/src/lib/craft-use.js.map +1 -0
- package/src/lib/craft-view-transition.d.ts +102 -0
- package/src/lib/craft-view-transition.d.ts.map +1 -0
- package/src/lib/craft-view-transition.js +130 -0
- package/src/lib/craft-view-transition.js.map +1 -0
- package/src/lib/dom-event-hook.d.ts +30 -0
- package/src/lib/dom-event-hook.d.ts.map +1 -0
- package/src/lib/dom-event-hook.js +16 -0
- package/src/lib/dom-event-hook.js.map +1 -0
- package/src/lib/fn-wrapper.d.ts +13 -0
- package/src/lib/fn-wrapper.d.ts.map +1 -0
- package/src/lib/fn-wrapper.js +66 -0
- package/src/lib/fn-wrapper.js.map +1 -0
- package/src/lib/form/craft-field.d.ts +155 -0
- package/src/lib/form/craft-field.d.ts.map +1 -0
- package/src/lib/form/craft-field.directive.d.ts +70 -0
- package/src/lib/form/craft-field.directive.d.ts.map +1 -0
- package/src/lib/form/craft-field.directive.js +549 -0
- package/src/lib/form/craft-field.directive.js.map +1 -0
- package/src/lib/form/craft-field.js +586 -0
- package/src/lib/form/craft-field.js.map +1 -0
- package/src/lib/form/field-exception.d.ts +62 -0
- package/src/lib/form/field-exception.d.ts.map +1 -0
- package/src/lib/form/field-exception.js +37 -0
- package/src/lib/form/field-exception.js.map +1 -0
- package/src/lib/form/field-lens.d.ts +29 -0
- package/src/lib/form/field-lens.d.ts.map +1 -0
- package/src/lib/form/field-lens.js +32 -0
- package/src/lib/form/field-lens.js.map +1 -0
- package/src/lib/form/insert-form-attributes.d.ts +69 -0
- package/src/lib/form/insert-form-attributes.d.ts.map +1 -0
- package/src/lib/form/insert-form-attributes.js +163 -0
- package/src/lib/form/insert-form-attributes.js.map +1 -0
- package/src/lib/form/insert-form-internals.d.ts +110 -0
- package/src/lib/form/insert-form-internals.d.ts.map +1 -0
- package/src/lib/form/insert-form-internals.js +276 -0
- package/src/lib/form/insert-form-internals.js.map +1 -0
- package/src/lib/form/insert-form-schema.d.ts +10 -0
- package/src/lib/form/insert-form-schema.d.ts.map +1 -0
- package/src/lib/form/insert-form-schema.js +62 -0
- package/src/lib/form/insert-form-schema.js.map +1 -0
- package/src/lib/form/insert-form-submit.d.ts +79 -0
- package/src/lib/form/insert-form-submit.d.ts.map +1 -0
- package/src/lib/form/insert-form-submit.js +126 -0
- package/src/lib/form/insert-form-submit.js.map +1 -0
- package/src/lib/form/insert-form.d.ts +39 -0
- package/src/lib/form/insert-form.d.ts.map +1 -0
- package/src/lib/form/insert-form.js +255 -0
- package/src/lib/form/insert-form.js.map +1 -0
- package/src/lib/form/insert-select-form-tree.d.ts +33 -0
- package/src/lib/form/insert-select-form-tree.d.ts.map +1 -0
- package/src/lib/form/insert-select-form-tree.js +144 -0
- package/src/lib/form/insert-select-form-tree.js.map +1 -0
- package/src/lib/form/insert-sub-form-field.d.ts +17 -0
- package/src/lib/form/insert-sub-form-field.d.ts.map +1 -0
- package/src/lib/form/insert-sub-form-field.js +41 -0
- package/src/lib/form/insert-sub-form-field.js.map +1 -0
- package/src/lib/form/make-form-tree-insert.d.ts +22 -0
- package/src/lib/form/make-form-tree-insert.d.ts.map +1 -0
- package/src/lib/form/make-form-tree-insert.js +43 -0
- package/src/lib/form/make-form-tree-insert.js.map +1 -0
- package/src/lib/form/target-form-field.d.ts +11 -0
- package/src/lib/form/target-form-field.d.ts.map +1 -0
- package/src/lib/form/target-form-field.js +1 -0
- package/src/lib/form/target-form-field.js.map +1 -0
- package/src/lib/form/validator.d.ts +174 -0
- package/src/lib/form/validator.d.ts.map +1 -0
- package/src/lib/form/validator.js +465 -0
- package/src/lib/form/validator.js.map +1 -0
- package/src/lib/from-event-to-source$.d.ts +210 -0
- package/src/lib/from-event-to-source$.d.ts.map +1 -0
- package/src/lib/from-event-to-source$.js +29 -0
- package/src/lib/from-event-to-source$.js.map +1 -0
- package/src/lib/global-persister-handler.service.d.ts +10 -0
- package/src/lib/global-persister-handler.service.d.ts.map +1 -0
- package/src/lib/global-persister-handler.service.js +40 -0
- package/src/lib/global-persister-handler.service.js.map +1 -0
- package/src/lib/host/craft-compat.d.ts +242 -0
- package/src/lib/host/craft-compat.d.ts.map +1 -0
- package/src/lib/host/craft-compat.js +444 -0
- package/src/lib/host/craft-compat.js.map +1 -0
- package/src/lib/host/craft-dom.d.ts +16 -0
- package/src/lib/host/craft-dom.d.ts.map +1 -0
- package/src/lib/host/craft-dom.js +24 -0
- package/src/lib/host/craft-dom.js.map +1 -0
- package/src/lib/host/craft-http.d.ts +22 -0
- package/src/lib/host/craft-http.d.ts.map +1 -0
- package/src/lib/host/craft-http.js +80 -0
- package/src/lib/host/craft-http.js.map +1 -0
- package/src/lib/host/craft-injector-host.d.ts +3 -0
- package/src/lib/host/craft-injector-host.d.ts.map +1 -0
- package/src/lib/host/craft-injector-host.js +2 -0
- package/src/lib/host/craft-injector-host.js.map +1 -0
- package/src/lib/host/craft-injector.d.ts +40 -0
- package/src/lib/host/craft-injector.d.ts.map +1 -0
- package/src/lib/host/craft-injector.js +318 -0
- package/src/lib/host/craft-injector.js.map +1 -0
- package/src/lib/host/craft-linked-signal.d.ts +17 -0
- package/src/lib/host/craft-linked-signal.d.ts.map +1 -0
- package/src/lib/host/craft-linked-signal.js +86 -0
- package/src/lib/host/craft-linked-signal.js.map +1 -0
- package/src/lib/host/craft-router-runtime.d.ts +61 -0
- package/src/lib/host/craft-router-runtime.d.ts.map +1 -0
- package/src/lib/host/craft-router-runtime.js +456 -0
- package/src/lib/host/craft-router-runtime.js.map +1 -0
- package/src/lib/host/craft-router-types.d.ts +84 -0
- package/src/lib/host/craft-router-types.d.ts.map +1 -0
- package/src/lib/host/craft-router-types.js +35 -0
- package/src/lib/host/craft-router-types.js.map +1 -0
- package/src/lib/host/craft-signal.d.ts +45 -0
- package/src/lib/host/craft-signal.d.ts.map +1 -0
- package/src/lib/host/craft-signal.js +161 -0
- package/src/lib/host/craft-signal.js.map +1 -0
- package/src/lib/host/craft-test-bed.d.ts +63 -0
- package/src/lib/host/craft-test-bed.d.ts.map +1 -0
- package/src/lib/host/craft-test-bed.js +114 -0
- package/src/lib/host/craft-test-bed.js.map +1 -0
- package/src/lib/host-tag.d.ts +2 -0
- package/src/lib/host-tag.d.ts.map +1 -0
- package/src/lib/host-tag.js +2 -0
- package/src/lib/host-tag.js.map +1 -0
- package/src/lib/insert-entities.d.ts +131 -0
- package/src/lib/insert-entities.d.ts.map +1 -0
- package/src/lib/insert-entities.js +159 -0
- package/src/lib/insert-entities.js.map +1 -0
- package/src/lib/insert-noop-typing-anchor.d.ts +15 -0
- package/src/lib/insert-noop-typing-anchor.d.ts.map +1 -0
- package/src/lib/insert-noop-typing-anchor.js +16 -0
- package/src/lib/insert-noop-typing-anchor.js.map +1 -0
- package/src/lib/insert-pagination-placeholder-data.d.ts +122 -0
- package/src/lib/insert-pagination-placeholder-data.d.ts.map +1 -0
- package/src/lib/insert-pagination-placeholder-data.js +244 -0
- package/src/lib/insert-pagination-placeholder-data.js.map +1 -0
- package/src/lib/insert-react-on-mutation.d.ts +261 -0
- package/src/lib/insert-react-on-mutation.d.ts.map +1 -0
- package/src/lib/insert-react-on-mutation.js +227 -0
- package/src/lib/insert-react-on-mutation.js.map +1 -0
- package/src/lib/insert-select-resource.d.ts +31 -0
- package/src/lib/insert-select-resource.d.ts.map +1 -0
- package/src/lib/insert-select-resource.js +27 -0
- package/src/lib/insert-select-resource.js.map +1 -0
- package/src/lib/insert-select.d.ts +126 -0
- package/src/lib/insert-select.d.ts.map +1 -0
- package/src/lib/insert-select.js +535 -0
- package/src/lib/insert-select.js.map +1 -0
- package/src/lib/insert-storage-persister.d.ts +27 -0
- package/src/lib/insert-storage-persister.d.ts.map +1 -0
- package/src/lib/insert-storage-persister.js +65 -0
- package/src/lib/insert-storage-persister.js.map +1 -0
- package/src/lib/insert-typed-pipes.d.ts +64 -0
- package/src/lib/insert-typed-pipes.d.ts.map +1 -0
- package/src/lib/insert-typed-pipes.js +32 -0
- package/src/lib/insert-typed-pipes.js.map +1 -0
- package/src/lib/linked-source.d.ts +8 -0
- package/src/lib/linked-source.d.ts.map +1 -0
- package/src/lib/linked-source.js +24 -0
- package/src/lib/linked-source.js.map +1 -0
- package/src/lib/local-storage-persister.d.ts +4 -0
- package/src/lib/local-storage-persister.d.ts.map +1 -0
- package/src/lib/local-storage-persister.js +342 -0
- package/src/lib/local-storage-persister.js.map +1 -0
- package/src/lib/middleware-schema-shared.d.ts +67 -0
- package/src/lib/middleware-schema-shared.d.ts.map +1 -0
- package/src/lib/middleware-schema-shared.js +34 -0
- package/src/lib/middleware-schema-shared.js.map +1 -0
- package/src/lib/mock-http-request-for-route.d.ts +173 -0
- package/src/lib/mock-http-request-for-route.d.ts.map +1 -0
- package/src/lib/mock-http-request-for-route.js +127 -0
- package/src/lib/mock-http-request-for-route.js.map +1 -0
- package/src/lib/mutation.d.ts +332 -0
- package/src/lib/mutation.d.ts.map +1 -0
- package/src/lib/mutation.js +923 -0
- package/src/lib/mutation.js.map +1 -0
- package/src/lib/on$.d.ts +26 -0
- package/src/lib/on$.d.ts.map +1 -0
- package/src/lib/on$.js +19 -0
- package/src/lib/on$.js.map +1 -0
- package/src/lib/portable-server-function.d.ts +68 -0
- package/src/lib/portable-server-function.d.ts.map +1 -0
- package/src/lib/portable-server-function.js +97 -0
- package/src/lib/portable-server-function.js.map +1 -0
- package/src/lib/preserved-resource.d.ts +4 -0
- package/src/lib/preserved-resource.d.ts.map +1 -0
- package/src/lib/preserved-resource.js +60 -0
- package/src/lib/preserved-resource.js.map +1 -0
- package/src/lib/primitive-method-runtime-context.d.ts +28 -0
- package/src/lib/primitive-method-runtime-context.d.ts.map +1 -0
- package/src/lib/primitive-method-runtime-context.js +38 -0
- package/src/lib/primitive-method-runtime-context.js.map +1 -0
- package/src/lib/primitive-resource-runtime-context.d.ts +46 -0
- package/src/lib/primitive-resource-runtime-context.d.ts.map +1 -0
- package/src/lib/primitive-resource-runtime-context.js +102 -0
- package/src/lib/primitive-resource-runtime-context.js.map +1 -0
- package/src/lib/query-params.d.ts +216 -0
- package/src/lib/query-params.d.ts.map +1 -0
- package/src/lib/query-params.js +324 -0
- package/src/lib/query-params.js.map +1 -0
- package/src/lib/query.core.d.ts +214 -0
- package/src/lib/query.core.d.ts.map +1 -0
- package/src/lib/query.core.js +210 -0
- package/src/lib/query.core.js.map +1 -0
- package/src/lib/query.d.ts +324 -0
- package/src/lib/query.d.ts.map +1 -0
- package/src/lib/query.js +971 -0
- package/src/lib/query.js.map +1 -0
- package/src/lib/reactive-read.d.ts +162 -0
- package/src/lib/reactive-read.d.ts.map +1 -0
- package/src/lib/reactive-read.js +389 -0
- package/src/lib/reactive-read.js.map +1 -0
- package/src/lib/resource-by-id.d.ts +71 -0
- package/src/lib/resource-by-id.d.ts.map +1 -0
- package/src/lib/resource-by-id.js +294 -0
- package/src/lib/resource-by-id.js.map +1 -0
- package/src/lib/resource-exception.d.ts +30 -0
- package/src/lib/resource-exception.d.ts.map +1 -0
- package/src/lib/resource-exception.js +86 -0
- package/src/lib/resource-exception.js.map +1 -0
- package/src/lib/route-checked-di.d.ts +229 -0
- package/src/lib/route-checked-di.d.ts.map +1 -0
- package/src/lib/route-checked-di.js +1 -0
- package/src/lib/route-checked-di.js.map +1 -0
- package/src/lib/schema-validation.d.ts +89 -0
- package/src/lib/schema-validation.d.ts.map +1 -0
- package/src/lib/schema-validation.js +110 -0
- package/src/lib/schema-validation.js.map +1 -0
- package/src/lib/send-context-to-ai.d.ts +20 -0
- package/src/lib/send-context-to-ai.d.ts.map +1 -0
- package/src/lib/send-context-to-ai.js +18 -0
- package/src/lib/send-context-to-ai.js.map +1 -0
- package/src/lib/send-context-to-ai.tokens.d.ts +12 -0
- package/src/lib/send-context-to-ai.tokens.d.ts.map +1 -0
- package/src/lib/send-context-to-ai.tokens.js +1 -0
- package/src/lib/send-context-to-ai.tokens.js.map +1 -0
- package/src/lib/server-function-client.d.ts +102 -0
- package/src/lib/server-function-client.d.ts.map +1 -0
- package/src/lib/server-function-client.js +106 -0
- package/src/lib/server-function-client.js.map +1 -0
- package/src/lib/server-function-contract.d.ts +42 -0
- package/src/lib/server-function-contract.d.ts.map +1 -0
- package/src/lib/server-function-contract.js +23 -0
- package/src/lib/server-function-contract.js.map +1 -0
- package/src/lib/server-function-middleware.d.ts +222 -0
- package/src/lib/server-function-middleware.d.ts.map +1 -0
- package/src/lib/server-function-middleware.js +189 -0
- package/src/lib/server-function-middleware.js.map +1 -0
- package/src/lib/server-function.d.ts +114 -0
- package/src/lib/server-function.d.ts.map +1 -0
- package/src/lib/server-function.js +80 -0
- package/src/lib/server-function.js.map +1 -0
- package/src/lib/server-layer.d.ts +185 -0
- package/src/lib/server-layer.d.ts.map +1 -0
- package/src/lib/server-layer.js +121 -0
- package/src/lib/server-layer.js.map +1 -0
- package/src/lib/server.d.ts +83 -0
- package/src/lib/server.d.ts.map +1 -0
- package/src/lib/server.js +266 -0
- package/src/lib/server.js.map +1 -0
- package/src/lib/setup-craft-service-test.d.ts +90 -0
- package/src/lib/setup-craft-service-test.d.ts.map +1 -0
- package/src/lib/setup-craft-service-test.js +193 -0
- package/src/lib/setup-craft-service-test.js.map +1 -0
- package/src/lib/setup-craft-service-testing-by-register.d.ts +245 -0
- package/src/lib/setup-craft-service-testing-by-register.d.ts.map +1 -0
- package/src/lib/setup-craft-service-testing-by-register.js +316 -0
- package/src/lib/setup-craft-service-testing-by-register.js.map +1 -0
- package/src/lib/signal-proxy.d.ts +21 -0
- package/src/lib/signal-proxy.d.ts.map +1 -0
- package/src/lib/signal-proxy.js +79 -0
- package/src/lib/signal-proxy.js.map +1 -0
- package/src/lib/signal-source.d.ts +392 -0
- package/src/lib/signal-source.d.ts.map +1 -0
- package/src/lib/signal-source.js +433 -0
- package/src/lib/signal-source.js.map +1 -0
- package/src/lib/source$.d.ts +121 -0
- package/src/lib/source$.d.ts.map +1 -0
- package/src/lib/source$.js +171 -0
- package/src/lib/source$.js.map +1 -0
- package/src/lib/source-from-event.d.ts +350 -0
- package/src/lib/source-from-event.d.ts.map +1 -0
- package/src/lib/source-from-event.js +26 -0
- package/src/lib/source-from-event.js.map +1 -0
- package/src/lib/stacked-source.d.ts +6 -0
- package/src/lib/stacked-source.d.ts.map +1 -0
- package/src/lib/stacked-source.js +29 -0
- package/src/lib/stacked-source.js.map +1 -0
- package/src/lib/standard-schema.d.ts +43 -0
- package/src/lib/standard-schema.d.ts.map +1 -0
- package/src/lib/standard-schema.js +1 -0
- package/src/lib/standard-schema.js.map +1 -0
- package/src/lib/state-method-runtime-context.d.ts +13 -0
- package/src/lib/state-method-runtime-context.d.ts.map +1 -0
- package/src/lib/state-method-runtime-context.js +11 -0
- package/src/lib/state-method-runtime-context.js.map +1 -0
- package/src/lib/state.d.ts +158 -0
- package/src/lib/state.d.ts.map +1 -0
- package/src/lib/state.js +388 -0
- package/src/lib/state.js.map +1 -0
- package/src/lib/storage-persister.service.d.ts +25 -0
- package/src/lib/storage-persister.service.d.ts.map +1 -0
- package/src/lib/storage-persister.service.js +27 -0
- package/src/lib/storage-persister.service.js.map +1 -0
- package/src/lib/take-app-snapshot.d.ts +31 -0
- package/src/lib/take-app-snapshot.d.ts.map +1 -0
- package/src/lib/take-app-snapshot.js +93 -0
- package/src/lib/take-app-snapshot.js.map +1 -0
- package/src/lib/template-trace.d.ts +37 -0
- package/src/lib/template-trace.d.ts.map +1 -0
- package/src/lib/template-trace.js +37 -0
- package/src/lib/template-trace.js.map +1 -0
- package/src/lib/temporal-runtime.d.ts +146 -0
- package/src/lib/temporal-runtime.d.ts.map +1 -0
- package/src/lib/temporal-runtime.js +375 -0
- package/src/lib/temporal-runtime.js.map +1 -0
- package/src/lib/to-source.d.ts +335 -0
- package/src/lib/to-source.d.ts.map +1 -0
- package/src/lib/to-source.js +359 -0
- package/src/lib/to-source.js.map +1 -0
- package/src/lib/util/craft-resource-ref.d.ts +29 -0
- package/src/lib/util/craft-resource-ref.d.ts.map +1 -0
- package/src/lib/util/craft-resource-ref.js +1 -0
- package/src/lib/util/craft-resource-ref.js.map +1 -0
- package/src/lib/util/craft-resource-status.d.ts +17 -0
- package/src/lib/util/craft-resource-status.d.ts.map +1 -0
- package/src/lib/util/craft-resource-status.js +14 -0
- package/src/lib/util/craft-resource-status.js.map +1 -0
- package/src/lib/util/entities-util.d.ts +340 -0
- package/src/lib/util/entities-util.d.ts.map +1 -0
- package/src/lib/util/entities-util.js +136 -0
- package/src/lib/util/entities-util.js.map +1 -0
- package/src/lib/util/explicit-effect.d.ts +42 -0
- package/src/lib/util/explicit-effect.d.ts.map +1 -0
- package/src/lib/util/explicit-effect.js +37 -0
- package/src/lib/util/explicit-effect.js.map +1 -0
- package/src/lib/util/extract-signal-props-and-methods.d.ts +20 -0
- package/src/lib/util/extract-signal-props-and-methods.d.ts.map +1 -0
- package/src/lib/util/extract-signal-props-and-methods.js +1 -0
- package/src/lib/util/extract-signal-props-and-methods.js.map +1 -0
- package/src/lib/util/method-trigger-nonce.d.ts +45 -0
- package/src/lib/util/method-trigger-nonce.d.ts.map +1 -0
- package/src/lib/util/method-trigger-nonce.js +58 -0
- package/src/lib/util/method-trigger-nonce.js.map +1 -0
- package/src/lib/util/persister.type.d.ts +37 -0
- package/src/lib/util/persister.type.d.ts.map +1 -0
- package/src/lib/util/persister.type.js +1 -0
- package/src/lib/util/persister.type.js.map +1 -0
- package/src/lib/util/persister.util.d.ts +8 -0
- package/src/lib/util/persister.util.d.ts.map +1 -0
- package/src/lib/util/persister.util.js +71 -0
- package/src/lib/util/persister.util.js.map +1 -0
- package/src/lib/util/react-on-mutation-effect.d.ts +16 -0
- package/src/lib/util/react-on-mutation-effect.d.ts.map +1 -0
- package/src/lib/util/react-on-mutation-effect.js +148 -0
- package/src/lib/util/react-on-mutation-effect.js.map +1 -0
- package/src/lib/util/resource-by-id-changes-tracker.util.d.ts +27 -0
- package/src/lib/util/resource-by-id-changes-tracker.util.d.ts.map +1 -0
- package/src/lib/util/resource-by-id-changes-tracker.util.js +97 -0
- package/src/lib/util/resource-by-id-changes-tracker.util.js.map +1 -0
- package/src/lib/util/source.type.d.ts +6 -0
- package/src/lib/util/source.type.d.ts.map +1 -0
- package/src/lib/util/source.type.js +1 -0
- package/src/lib/util/source.type.js.map +1 -0
- package/src/lib/util/types/access-type-object-property-by-dotted-path.type.d.ts +4 -0
- package/src/lib/util/types/access-type-object-property-by-dotted-path.type.d.ts.map +1 -0
- package/src/lib/util/types/access-type-object-property-by-dotted-path.type.js +1 -0
- package/src/lib/util/types/access-type-object-property-by-dotted-path.type.js.map +1 -0
- package/src/lib/util/types/boolean-or-mapper-fn-by-path-by-id.type.d.ts +27 -0
- package/src/lib/util/types/boolean-or-mapper-fn-by-path-by-id.type.d.ts.map +1 -0
- package/src/lib/util/types/boolean-or-mapper-fn-by-path-by-id.type.js +1 -0
- package/src/lib/util/types/boolean-or-mapper-fn-by-path-by-id.type.js.map +1 -0
- package/src/lib/util/types/boolean-or-mapper-fn-by-path.type.d.ts +24 -0
- package/src/lib/util/types/boolean-or-mapper-fn-by-path.type.d.ts.map +1 -0
- package/src/lib/util/types/boolean-or-mapper-fn-by-path.type.js +1 -0
- package/src/lib/util/types/boolean-or-mapper-fn-by-path.type.js.map +1 -0
- package/src/lib/util/types/brand.d.ts +7 -0
- package/src/lib/util/types/brand.d.ts.map +1 -0
- package/src/lib/util/types/brand.js +9 -0
- package/src/lib/util/types/brand.js.map +1 -0
- package/src/lib/util/types/object-deep-path-mapper.type.d.ts +13 -0
- package/src/lib/util/types/object-deep-path-mapper.type.d.ts.map +1 -0
- package/src/lib/util/types/object-deep-path-mapper.type.js +1 -0
- package/src/lib/util/types/object-deep-path-mapper.type.js.map +1 -0
- package/src/lib/util/types/resource-by-id-config.type.d.ts +115 -0
- package/src/lib/util/types/resource-by-id-config.type.d.ts.map +1 -0
- package/src/lib/util/types/resource-by-id-config.type.js +1 -0
- package/src/lib/util/types/resource-by-id-config.type.js.map +1 -0
- package/src/lib/util/types/resource-with-params-or-params-fn.type.d.ts +52 -0
- package/src/lib/util/types/resource-with-params-or-params-fn.type.d.ts.map +1 -0
- package/src/lib/util/types/resource-with-params-or-params-fn.type.js +1 -0
- package/src/lib/util/types/resource-with-params-or-params-fn.type.js.map +1 -0
- package/src/lib/util/types/shared.type.d.ts +66 -0
- package/src/lib/util/types/shared.type.d.ts.map +1 -0
- package/src/lib/util/types/shared.type.js +1 -0
- package/src/lib/util/types/shared.type.js.map +1 -0
- package/src/lib/util/types/util.d.ts +16 -0
- package/src/lib/util/types/util.d.ts.map +1 -0
- package/src/lib/util/types/util.js +60 -0
- package/src/lib/util/types/util.js.map +1 -0
- package/src/lib/util/types/util.type.d.ts +67 -0
- package/src/lib/util/types/util.type.d.ts.map +1 -0
- package/src/lib/util/types/util.type.js +5 -0
- package/src/lib/util/types/util.type.js.map +1 -0
- package/src/lib/util/update-state.util.d.ts +10 -0
- package/src/lib/util/update-state.util.d.ts.map +1 -0
- package/src/lib/util/update-state.util.js +31 -0
- package/src/lib/util/update-state.util.js.map +1 -0
- package/src/lib/util/util.d.ts +19 -0
- package/src/lib/util/util.d.ts.map +1 -0
- package/src/lib/util/util.js +50 -0
- package/src/lib/util/util.js.map +1 -0
- package/src/lib/util/util.type.d.ts +107 -0
- package/src/lib/util/util.type.d.ts.map +1 -0
- package/src/lib/util/util.type.js +9 -0
- package/src/lib/util/util.type.js.map +1 -0
- package/src/lib/yieldable.d.ts +94 -0
- package/src/lib/yieldable.d.ts.map +1 -0
- package/src/lib/yieldable.js +109 -0
- package/src/lib/yieldable.js.map +1 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { assertInInjectionContext, DestroyRef, EventEmitter, inject, Injector, signal, } from './host/craft-compat';
|
|
2
|
+
import { takeUntilDestroyed } from './host/craft-compat';
|
|
3
|
+
import { ɵcreateHostTaggedInjector, ɵHOST_TAG_LIST } from './craft-service';
|
|
4
|
+
import { APP_SNAPSHOT_REGISTRY } from './take-app-snapshot';
|
|
5
|
+
import { createNamedPrimitiveGen, } from './craft-primitive-gen';
|
|
6
|
+
import { yieldableInvocation } from './yieldable';
|
|
7
|
+
import { SourceBranded } from './util/util';
|
|
8
|
+
/**
|
|
9
|
+
* Creates an event emitter with automatic cleanup and signal-based value tracking.
|
|
10
|
+
*
|
|
11
|
+
* `source$` provides a lightweight event streaming solution that combines event emission,
|
|
12
|
+
* automatic subscription cleanup via `DestroyRef`, and signal-based reactive value tracking.
|
|
13
|
+
*
|
|
14
|
+
* @template T - The type of values emitted by the source
|
|
15
|
+
*
|
|
16
|
+
* @param name - Name matching the variable/property this source is assigned to (used for host
|
|
17
|
+
* tagging and dev-tools snapshot reporting, consistent with `craftComputed`/`craftEffect`)
|
|
18
|
+
*
|
|
19
|
+
* @returns {Source$<T>} A source object that is also a named primitive
|
|
20
|
+
* generator. Use it directly with `emit()`/`subscribe()`, or consume it with
|
|
21
|
+
* `yield*` to obtain `{ [name]: source }` and propagate its dependency metadata.
|
|
22
|
+
* - `emit(value: T)` - Emits a value to all subscribers and updates the internal signal
|
|
23
|
+
* - `subscribe(callback: (value: T) => void)` - Subscribes to emissions with automatic cleanup
|
|
24
|
+
* - `value: Signal<T | undefined>` - A read-only signal containing the last emitted value
|
|
25
|
+
* - `asReadonly()` - Returns a read-only version (only `subscribe` and `value`)
|
|
26
|
+
* - `preserveLastValue()` - Returns a variant that immediately emits the last value to new subscribers
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* Yieldable source service
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const { Reset } = craftService(
|
|
32
|
+
* { name: 'Reset', providedIn: 'global' },
|
|
33
|
+
* function* () {
|
|
34
|
+
* const reset$ = yield* source$<void>('reset$');
|
|
35
|
+
* return reset$;
|
|
36
|
+
* },
|
|
37
|
+
* );
|
|
38
|
+
*
|
|
39
|
+
* const reset = yield* Reset();
|
|
40
|
+
* reset.emit();
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* Basic usage with state coordination
|
|
45
|
+
* ```typescript
|
|
46
|
+
* import { source$, state, on$ } from '@craft-ts/core';
|
|
47
|
+
*
|
|
48
|
+
* @Component({
|
|
49
|
+
* selector: 'app-counter',
|
|
50
|
+
* template: `
|
|
51
|
+
* <p>Count: {{ counter() }}</p>
|
|
52
|
+
* <button (click)="counter.increment()">+1</button>
|
|
53
|
+
* <button (click)="reset$.emit()">Reset</button>
|
|
54
|
+
* `,
|
|
55
|
+
* })
|
|
56
|
+
* export class CounterComponent {
|
|
57
|
+
* reset$ = source$<void>('reset$');
|
|
58
|
+
*
|
|
59
|
+
* counter = craftUse(state(0, ({ set, update }) => ({
|
|
60
|
+
* increment: () => update((v) => v + 1),
|
|
61
|
+
* reset: on$(this.reset$, () => set(0)),
|
|
62
|
+
* })));
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* Late subscriber with preserved last value
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const notifications$ = source$<string>('notifications$').preserveLastValue();
|
|
71
|
+
*
|
|
72
|
+
* notifications$.emit('Server started');
|
|
73
|
+
* notifications$.emit('Database connected');
|
|
74
|
+
*
|
|
75
|
+
* // Late subscriber receives the last value immediately
|
|
76
|
+
* notifications$.subscribe((msg) => {
|
|
77
|
+
* console.log(msg); // 'Database connected'
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* Read-only access pattern
|
|
83
|
+
* ```typescript
|
|
84
|
+
* class DataService {
|
|
85
|
+
* private dataUpdated$ = source$<Data>('dataUpdated$');
|
|
86
|
+
* readonly dataUpdated = this.dataUpdated$.asReadonly();
|
|
87
|
+
*
|
|
88
|
+
* updateData(data: Data) {
|
|
89
|
+
* this.dataUpdated$.emit(data);
|
|
90
|
+
* }
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @see {@link https://craft-ts.dev/utils/source$ | source$ documentation}
|
|
95
|
+
*/
|
|
96
|
+
export function source$(name) {
|
|
97
|
+
assertInInjectionContext(source$);
|
|
98
|
+
const injector = inject(Injector);
|
|
99
|
+
const sourceInjector = ɵcreateHostTaggedInjector(injector, `source:${name}`);
|
|
100
|
+
const sourceRef$ = new EventEmitter();
|
|
101
|
+
const destroyRef = inject(DestroyRef);
|
|
102
|
+
const sourceAsSignal = signal(undefined);
|
|
103
|
+
const registry = inject(APP_SNAPSHOT_REGISTRY, { optional: true });
|
|
104
|
+
if (registry) {
|
|
105
|
+
const from = sourceInjector.get(ɵHOST_TAG_LIST, null) ?? [];
|
|
106
|
+
registry.triggerSnapshot$
|
|
107
|
+
.pipe(takeUntilDestroyed(destroyRef))
|
|
108
|
+
.subscribe(() => {
|
|
109
|
+
let stateSnapshot;
|
|
110
|
+
try {
|
|
111
|
+
stateSnapshot = sourceAsSignal();
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
stateSnapshot = {
|
|
115
|
+
error: error instanceof Error ? error.message : String(error),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
registry.allSnapShot$.next({
|
|
119
|
+
source: name,
|
|
120
|
+
from,
|
|
121
|
+
state: stateSnapshot,
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const source = {
|
|
126
|
+
...SourceBranded,
|
|
127
|
+
emit: (value) => {
|
|
128
|
+
sourceRef$.emit(value);
|
|
129
|
+
sourceAsSignal.set(value);
|
|
130
|
+
return yieldableInvocation(undefined);
|
|
131
|
+
},
|
|
132
|
+
subscribe: (callback) => sourceRef$.subscribe(callback),
|
|
133
|
+
preserveLastValue: () => {
|
|
134
|
+
const sourceWithLastValueRef = new EventEmitter();
|
|
135
|
+
const subscriptionWithLastLastValue = sourceRef$.subscribe((value) => {
|
|
136
|
+
sourceWithLastValueRef.emit(value);
|
|
137
|
+
});
|
|
138
|
+
destroyRef.onDestroy(() => subscriptionWithLastLastValue.unsubscribe());
|
|
139
|
+
return {
|
|
140
|
+
...SourceBranded,
|
|
141
|
+
emit: (value) => {
|
|
142
|
+
sourceWithLastValueRef.emit(value);
|
|
143
|
+
sourceAsSignal.set(value);
|
|
144
|
+
return yieldableInvocation(undefined);
|
|
145
|
+
},
|
|
146
|
+
subscribe: (callback) => {
|
|
147
|
+
sourceWithLastValueRef.subscribe(callback);
|
|
148
|
+
sourceWithLastValueRef.emit(sourceAsSignal());
|
|
149
|
+
},
|
|
150
|
+
asReadonly: () => ({
|
|
151
|
+
...SourceBranded,
|
|
152
|
+
subscribe: (callback) => {
|
|
153
|
+
sourceWithLastValueRef.subscribe(callback);
|
|
154
|
+
sourceWithLastValueRef.emit(sourceAsSignal());
|
|
155
|
+
},
|
|
156
|
+
value: sourceAsSignal.asReadonly(),
|
|
157
|
+
}),
|
|
158
|
+
value: sourceAsSignal.asReadonly(),
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
value: sourceAsSignal.asReadonly(),
|
|
162
|
+
asReadonly: () => ({
|
|
163
|
+
...SourceBranded,
|
|
164
|
+
subscribe: (callback) => sourceRef$.subscribe(callback),
|
|
165
|
+
value: sourceAsSignal.asReadonly(),
|
|
166
|
+
}),
|
|
167
|
+
};
|
|
168
|
+
const generator = createNamedPrimitiveGen(name, source);
|
|
169
|
+
return Object.assign(generator, source);
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=source$.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source$.js","sourceRoot":"","sources":["../../../../../libs/core/src/lib/source$.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,UAAU,EACV,YAAY,EACZ,MAAM,EACN,QAAQ,EAER,MAAM,GACP,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAK5D,OAAO,EACL,uBAAuB,GAExB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAoD5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuFG;AACH,MAAM,UAAU,OAAO,CACrB,IAAU;IAEV,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,cAAc,GAAG,yBAAyB,CAAC,QAAQ,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;IAE7E,MAAM,UAAU,GAAG,IAAI,YAAY,EAAK,CAAC;IACzC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAEtC,MAAM,cAAc,GAAG,MAAM,CAAgB,SAAS,CAAC,CAAC;IAExD,MAAM,QAAQ,GAAG,MAAM,CAAC,qBAAqB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5D,QAAQ,CAAC,gBAAgB;aACtB,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;aACpC,SAAS,CAAC,GAAG,EAAE;YACd,IAAI,aAAsB,CAAC;YAC3B,IAAI,CAAC;gBACH,aAAa,GAAG,cAAc,EAAE,CAAC;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,aAAa,GAAG;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC;YACJ,CAAC;YACD,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC;gBACzB,MAAM,EAAE,IAAI;gBACZ,IAAI;gBACJ,KAAK,EAAE,aAAa;aACrB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,MAAM,MAAM,GAAG;QACb,GAAG,aAAa;QAChB,IAAI,EAAE,CAAC,KAAQ,EAAE,EAAE;YACjB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1B,OAAO,mBAAmB,CAAc,SAAS,CAAC,CAAC;QACrD,CAAC;QACD,SAAS,EAAE,CAAC,QAA4B,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC;QAC3E,iBAAiB,EAAE,GAAG,EAAE;YACtB,MAAM,sBAAsB,GAAG,IAAI,YAAY,EAAK,CAAC;YACrD,MAAM,6BAA6B,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;gBACnE,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC;YAEH,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,6BAA6B,CAAC,WAAW,EAAE,CAAC,CAAC;YAExE,OAAO;gBACL,GAAG,aAAa;gBAChB,IAAI,EAAE,CAAC,KAAQ,EAAE,EAAE;oBACjB,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACnC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBAC1B,OAAO,mBAAmB,CAAc,SAAS,CAAC,CAAC;gBACrD,CAAC;gBACD,SAAS,EAAE,CAAC,QAA4B,EAAE,EAAE;oBAC1C,sBAAsB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;oBAC3C,sBAAsB,CAAC,IAAI,CAAC,cAAc,EAAO,CAAC,CAAC;gBACrD,CAAC;gBACD,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;oBACjB,GAAG,aAAa;oBAChB,SAAS,EAAE,CAAC,QAA4B,EAAE,EAAE;wBAC1C,sBAAsB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;wBAC3C,sBAAsB,CAAC,IAAI,CAAC,cAAc,EAAO,CAAC,CAAC;oBACrD,CAAC;oBACD,KAAK,EAAE,cAAc,CAAC,UAAU,EAAE;iBACnC,CAAC;gBACF,KAAK,EAAE,cAAc,CAAC,UAAU,EAAE;aACnC,CAAC;QACJ,CAAC;QACD,KAAK,EAAE,cAAc,CAAC,UAAU,EAAE;QAClC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;YACjB,GAAG,aAAa;YAChB,SAAS,EAAE,CAAC,QAA4B,EAAE,EAAE,CAC1C,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC;YAChC,KAAK,EAAE,cAAc,CAAC,UAAU,EAAE;SACnC,CAAC;KACmC,CAAC;IAExC,MAAM,SAAS,GAAG,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAExD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAqB,CAAC;AAC9D,CAAC","sourcesContent":["import {\n assertInInjectionContext,\n DestroyRef,\n EventEmitter,\n inject,\n Injector,\n Signal,\n signal,\n} from './host/craft-compat';\nimport { takeUntilDestroyed } from './host/craft-compat';\nimport { ɵcreateHostTaggedInjector, ɵHOST_TAG_LIST } from './craft-service';\nimport { APP_SNAPSHOT_REGISTRY } from './take-app-snapshot';\nimport type {\n SERVICE_HELPER_DEPENDENCIES,\n ServiceDependencies,\n} from './craft-service';\nimport {\n createNamedPrimitiveGen,\n type NamedCraftPrimitiveGen,\n} from './craft-primitive-gen';\nimport { yieldableInvocation } from './yieldable';\nimport { SourceBranded } from './util/util';\n\nexport type SourceDependency<Name extends string> = {\n [K in Name]: ServiceDependencies<'function', {}>;\n};\n\ntype SourceDependencyCarrier<Name extends string> = {\n readonly [SERVICE_HELPER_DEPENDENCIES]?: SourceDependency<Name>;\n};\n\nexport type SourceSubscribe<T> = {\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n};\n\nexport type SourceInstance<\n T,\n Name extends string = string,\n> = SourceDependencyCarrier<Name> & {\n emit: (value: T) => void;\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n asReadonly: () => ReadonlySource$<T, Name>;\n preserveLastValue: () => PreservedSource$<T, Name>;\n value: Signal<T | undefined>;\n};\n\nexport type Source$<T, Name extends string = string> = SourceInstance<T, Name> &\n NamedCraftPrimitiveGen<Name, SourceInstance<T, Name>>;\n\nexport type PreservedSource$<\n T,\n Name extends string = string,\n> = SourceDependencyCarrier<Name> & {\n emit: (value: T) => void;\n subscribe: (callback: (value: T) => void) => void;\n asReadonly: () => ReadonlySource$<T, Name>;\n value: Signal<T | undefined>;\n};\n\nexport type ReadonlySource$<\n T,\n Name extends string = string,\n> = SourceDependencyCarrier<Name> & {\n subscribe: (\n callback: (value: T) => void,\n ) => ReturnType<EventEmitter<T>['subscribe']>;\n value: Signal<T | undefined>;\n};\n\n/**\n * Creates an event emitter with automatic cleanup and signal-based value tracking.\n *\n * `source$` provides a lightweight event streaming solution that combines event emission,\n * automatic subscription cleanup via `DestroyRef`, and signal-based reactive value tracking.\n *\n * @template T - The type of values emitted by the source\n *\n * @param name - Name matching the variable/property this source is assigned to (used for host\n * tagging and dev-tools snapshot reporting, consistent with `craftComputed`/`craftEffect`)\n *\n * @returns {Source$<T>} A source object that is also a named primitive\n * generator. Use it directly with `emit()`/`subscribe()`, or consume it with\n * `yield*` to obtain `{ [name]: source }` and propagate its dependency metadata.\n * - `emit(value: T)` - Emits a value to all subscribers and updates the internal signal\n * - `subscribe(callback: (value: T) => void)` - Subscribes to emissions with automatic cleanup\n * - `value: Signal<T | undefined>` - A read-only signal containing the last emitted value\n * - `asReadonly()` - Returns a read-only version (only `subscribe` and `value`)\n * - `preserveLastValue()` - Returns a variant that immediately emits the last value to new subscribers\n *\n * @example\n * Yieldable source service\n * ```typescript\n * const { Reset } = craftService(\n * { name: 'Reset', providedIn: 'global' },\n * function* () {\n * const reset$ = yield* source$<void>('reset$');\n * return reset$;\n * },\n * );\n *\n * const reset = yield* Reset();\n * reset.emit();\n * ```\n *\n * @example\n * Basic usage with state coordination\n * ```typescript\n * import { source$, state, on$ } from '@craft-ts/core';\n *\n * @Component({\n * selector: 'app-counter',\n * template: `\n * <p>Count: {{ counter() }}</p>\n * <button (click)=\"counter.increment()\">+1</button>\n * <button (click)=\"reset$.emit()\">Reset</button>\n * `,\n * })\n * export class CounterComponent {\n * reset$ = source$<void>('reset$');\n *\n * counter = craftUse(state(0, ({ set, update }) => ({\n * increment: () => update((v) => v + 1),\n * reset: on$(this.reset$, () => set(0)),\n * })));\n * }\n * ```\n *\n *\n * @example\n * Late subscriber with preserved last value\n * ```typescript\n * const notifications$ = source$<string>('notifications$').preserveLastValue();\n *\n * notifications$.emit('Server started');\n * notifications$.emit('Database connected');\n *\n * // Late subscriber receives the last value immediately\n * notifications$.subscribe((msg) => {\n * console.log(msg); // 'Database connected'\n * });\n * ```\n *\n * @example\n * Read-only access pattern\n * ```typescript\n * class DataService {\n * private dataUpdated$ = source$<Data>('dataUpdated$');\n * readonly dataUpdated = this.dataUpdated$.asReadonly();\n *\n * updateData(data: Data) {\n * this.dataUpdated$.emit(data);\n * }\n * }\n * ```\n *\n * @see {@link https://craft-ts.dev/utils/source$ | source$ documentation}\n */\nexport function source$<T, Name extends string = string>(\n name: Name,\n): Source$<T, Name> {\n assertInInjectionContext(source$);\n const injector = inject(Injector);\n const sourceInjector = ɵcreateHostTaggedInjector(injector, `source:${name}`);\n\n const sourceRef$ = new EventEmitter<T>();\n const destroyRef = inject(DestroyRef);\n\n const sourceAsSignal = signal<T | undefined>(undefined);\n\n const registry = inject(APP_SNAPSHOT_REGISTRY, { optional: true });\n if (registry) {\n const from = sourceInjector.get(ɵHOST_TAG_LIST, null) ?? [];\n registry.triggerSnapshot$\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(() => {\n let stateSnapshot: unknown;\n try {\n stateSnapshot = sourceAsSignal();\n } catch (error) {\n stateSnapshot = {\n error: error instanceof Error ? error.message : String(error),\n };\n }\n registry.allSnapShot$.next({\n source: name,\n from,\n state: stateSnapshot,\n });\n });\n }\n\n const source = {\n ...SourceBranded,\n emit: (value: T) => {\n sourceRef$.emit(value);\n sourceAsSignal.set(value);\n return yieldableInvocation<never, void>(undefined);\n },\n subscribe: (callback: (value: T) => void) => sourceRef$.subscribe(callback),\n preserveLastValue: () => {\n const sourceWithLastValueRef = new EventEmitter<T>();\n const subscriptionWithLastLastValue = sourceRef$.subscribe((value) => {\n sourceWithLastValueRef.emit(value);\n });\n\n destroyRef.onDestroy(() => subscriptionWithLastLastValue.unsubscribe());\n\n return {\n ...SourceBranded,\n emit: (value: T) => {\n sourceWithLastValueRef.emit(value);\n sourceAsSignal.set(value);\n return yieldableInvocation<never, void>(undefined);\n },\n subscribe: (callback: (value: T) => void) => {\n sourceWithLastValueRef.subscribe(callback);\n sourceWithLastValueRef.emit(sourceAsSignal() as T);\n },\n asReadonly: () => ({\n ...SourceBranded,\n subscribe: (callback: (value: T) => void) => {\n sourceWithLastValueRef.subscribe(callback);\n sourceWithLastValueRef.emit(sourceAsSignal() as T);\n },\n value: sourceAsSignal.asReadonly(),\n }),\n value: sourceAsSignal.asReadonly(),\n };\n },\n value: sourceAsSignal.asReadonly(),\n asReadonly: () => ({\n ...SourceBranded,\n subscribe: (callback: (value: T) => void) =>\n sourceRef$.subscribe(callback),\n value: sourceAsSignal.asReadonly(),\n }),\n } as unknown as SourceInstance<T, Name>;\n\n const generator = createNamedPrimitiveGen(name, source);\n\n return Object.assign(generator, source) as Source$<T, Name>;\n}\n"]}
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { ValueEqualityFn } from './host/craft-compat';
|
|
2
|
+
import { SignalSource } from './signal-source';
|
|
3
|
+
export type SourceFromEvent<T> = SignalSource<T> & {
|
|
4
|
+
dispose: () => void;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Creates a source from DOM events with automatic cleanup on component destruction.
|
|
8
|
+
*
|
|
9
|
+
* This function bridges DOM events with craft-ts's reactive system by:
|
|
10
|
+
* - Converting native DOM events to source emissions
|
|
11
|
+
* - Automatically removing event listeners on component destruction
|
|
12
|
+
* - Supporting optional event payload transformation
|
|
13
|
+
* - Providing manual disposal capability
|
|
14
|
+
* - Enabling event-driven query/mutation triggering
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* **Automatic Cleanup:**
|
|
18
|
+
* - Event listeners are automatically removed when the injection context is destroyed
|
|
19
|
+
* - Uses Angular's `DestroyRef` for lifecycle management
|
|
20
|
+
* - Manual cleanup available via `dispose()` method
|
|
21
|
+
* - Prevents memory leaks from dangling event listeners
|
|
22
|
+
*
|
|
23
|
+
* **Use Cases:**
|
|
24
|
+
* - **User interactions**: Click, input, scroll, keyboard events
|
|
25
|
+
* - **Window events**: Resize, scroll, focus, online/offline
|
|
26
|
+
* - **Document events**: Visibility changes, custom events
|
|
27
|
+
* - **Media events**: Video/audio play, pause, ended
|
|
28
|
+
* - **Form events**: Submit, change, input
|
|
29
|
+
* - **Custom events**: Application-specific DOM events
|
|
30
|
+
*
|
|
31
|
+
* **Event Transformation:**
|
|
32
|
+
* - Without `computedValue`: Emits the raw event object
|
|
33
|
+
* - With `computedValue`: Transforms event before emission
|
|
34
|
+
* - Useful for extracting specific event properties
|
|
35
|
+
* - Reduces payload size and improves type safety
|
|
36
|
+
*
|
|
37
|
+
* **Integration with Stores:**
|
|
38
|
+
* - Use source in queries/mutations via `afterRecomputation()`
|
|
39
|
+
* - Trigger async operations on DOM events
|
|
40
|
+
* - Coordinate multiple components via event sources
|
|
41
|
+
*
|
|
42
|
+
* **Injection Context:**
|
|
43
|
+
* - Must be called within Angular injection context
|
|
44
|
+
* - Typically called in component constructor or class fields
|
|
45
|
+
* - Uses `assertInInjectionContext()` for safety
|
|
46
|
+
*
|
|
47
|
+
* @template T - The type of the event object
|
|
48
|
+
* @template ComputedValue - The type after optional transformation
|
|
49
|
+
*
|
|
50
|
+
* @param target - The DOM element or event target to listen to.
|
|
51
|
+
* Can be any EventTarget (HTMLElement, Window, Document, etc.)
|
|
52
|
+
*
|
|
53
|
+
* @param eventName - The name of the event to listen for.
|
|
54
|
+
* Standard DOM event names: 'click', 'input', 'scroll', etc.
|
|
55
|
+
*
|
|
56
|
+
* @param options - Optional configuration:
|
|
57
|
+
* - `event`: Event listener options (capture, passive, once, etc.)
|
|
58
|
+
* - `computedValue`: Function to transform event before emission
|
|
59
|
+
* - `source`: Source options (equal)
|
|
60
|
+
*
|
|
61
|
+
* @returns A source that emits on DOM events with:
|
|
62
|
+
* - All standard source capabilities (set, preserveLastValue)
|
|
63
|
+
* - `dispose()`: Method to manually remove event listener
|
|
64
|
+
* - Automatic cleanup on component destruction
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* Basic click event source
|
|
68
|
+
* ```ts
|
|
69
|
+
* @Component({
|
|
70
|
+
* selector: 'app-clicker',
|
|
71
|
+
* template: '<button>Click me</button>',
|
|
72
|
+
* providers: [provideClickTrackerStore()],
|
|
73
|
+
* })
|
|
74
|
+
* export class ClickerComponent {
|
|
75
|
+
* store = ClickTrackerStore();
|
|
76
|
+
*
|
|
77
|
+
* // Mutation executes automatically on click
|
|
78
|
+
* }
|
|
79
|
+
*
|
|
80
|
+
* const { ClickTrackerStore, provideClickTrackerStore } = craftService(
|
|
81
|
+
* { name: 'ClickTrackerStore', providedIn: 'toProvide' },
|
|
82
|
+
* function* () {
|
|
83
|
+
* const hostElement = inject(ElementRef<HTMLElement>).nativeElement;
|
|
84
|
+
* const clickSource = sourceFromEvent<MouseEvent>(hostElement, 'click');
|
|
85
|
+
*
|
|
86
|
+
* const trackClick = yield* mutation({
|
|
87
|
+
* method: afterRecomputation(clickSource, (event) => ({
|
|
88
|
+
* x: event.clientX,
|
|
89
|
+
* y: event.clientY,
|
|
90
|
+
* })),
|
|
91
|
+
* loader: async ({ params }) => {
|
|
92
|
+
* await fetch('/api/track-click', {
|
|
93
|
+
* method: 'POST',
|
|
94
|
+
* body: JSON.stringify(params),
|
|
95
|
+
* });
|
|
96
|
+
* return { tracked: true };
|
|
97
|
+
* },
|
|
98
|
+
* });
|
|
99
|
+
*
|
|
100
|
+
* return { clickSource, trackClick };
|
|
101
|
+
* },
|
|
102
|
+
* );
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* Window scroll event with transformation
|
|
107
|
+
* ```ts
|
|
108
|
+
* @Component({
|
|
109
|
+
* selector: 'app-infinite-scroll',
|
|
110
|
+
* template: '...',
|
|
111
|
+
* providers: [provideInfiniteScrollStore()],
|
|
112
|
+
* })
|
|
113
|
+
* export class InfiniteScrollComponent {
|
|
114
|
+
* store = InfiniteScrollStore();
|
|
115
|
+
* }
|
|
116
|
+
*
|
|
117
|
+
* const { InfiniteScrollStore, provideInfiniteScrollStore } = craftService(
|
|
118
|
+
* { name: 'InfiniteScrollStore', providedIn: 'toProvide' },
|
|
119
|
+
* function* () {
|
|
120
|
+
* const scrollSource = sourceFromEvent(window, 'scroll', {
|
|
121
|
+
* computedValue: () => ({
|
|
122
|
+
* scrollY: window.scrollY,
|
|
123
|
+
* scrollHeight: document.documentElement.scrollHeight,
|
|
124
|
+
* clientHeight: window.innerHeight,
|
|
125
|
+
* }),
|
|
126
|
+
* event: { passive: true }, // Optimize performance
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* const checkLoadMore = yield* asyncProcess({
|
|
130
|
+
* method: afterRecomputation(scrollSource, (data) => data),
|
|
131
|
+
* loader: async ({ params }) => {
|
|
132
|
+
* const { scrollY, scrollHeight, clientHeight } = params;
|
|
133
|
+
* const nearBottom = scrollY + clientHeight >= scrollHeight - 100;
|
|
134
|
+
*
|
|
135
|
+
* if (nearBottom) {
|
|
136
|
+
* // Load more data
|
|
137
|
+
* const response = await fetch('/api/load-more');
|
|
138
|
+
* return response.json();
|
|
139
|
+
* }
|
|
140
|
+
* return null;
|
|
141
|
+
* },
|
|
142
|
+
* });
|
|
143
|
+
*
|
|
144
|
+
* return { scrollSource, checkLoadMore };
|
|
145
|
+
* },
|
|
146
|
+
* );
|
|
147
|
+
* ```
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* Form input event for real-time validation
|
|
151
|
+
* ```ts
|
|
152
|
+
* @Component({
|
|
153
|
+
* selector: 'app-search',
|
|
154
|
+
* template: '<input type="text" placeholder="Search..." />',
|
|
155
|
+
* providers: [provideSearchStore()],
|
|
156
|
+
* })
|
|
157
|
+
* export class SearchComponent {
|
|
158
|
+
* store = SearchStore();
|
|
159
|
+
*
|
|
160
|
+
* // Query executes on input changes
|
|
161
|
+
* }
|
|
162
|
+
*
|
|
163
|
+
* const { SearchStore, provideSearchStore } = craftService(
|
|
164
|
+
* { name: 'SearchStore', providedIn: 'toProvide' },
|
|
165
|
+
* function* () {
|
|
166
|
+
* const hostElement = inject(ElementRef<HTMLElement>).nativeElement;
|
|
167
|
+
* const inputSource = sourceFromEvent(hostElement, 'input', {
|
|
168
|
+
* computedValue: (event: Event) => {
|
|
169
|
+
* const target = event.target as HTMLInputElement;
|
|
170
|
+
* return target.value;
|
|
171
|
+
* },
|
|
172
|
+
* });
|
|
173
|
+
*
|
|
174
|
+
* const results = yield* query({
|
|
175
|
+
* method: afterRecomputation(inputSource, (term) => term),
|
|
176
|
+
* loader: async ({ params }) => {
|
|
177
|
+
* if (params.length < 3) return [];
|
|
178
|
+
*
|
|
179
|
+
* const response = await fetch(`/api/search?q=${params}`);
|
|
180
|
+
* return response.json();
|
|
181
|
+
* },
|
|
182
|
+
* });
|
|
183
|
+
*
|
|
184
|
+
* return { inputSource, results };
|
|
185
|
+
* },
|
|
186
|
+
* );
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* Window resize event updating a state
|
|
191
|
+
* ```ts
|
|
192
|
+
* @Component({
|
|
193
|
+
* selector: 'app-responsive',
|
|
194
|
+
* template: '...',
|
|
195
|
+
* })
|
|
196
|
+
* export class ResponsiveComponent {
|
|
197
|
+
* resizeSource = sourceFromEvent(window, 'resize', {
|
|
198
|
+
* computedValue: () => ({
|
|
199
|
+
* width: window.innerWidth,
|
|
200
|
+
* height: window.innerHeight,
|
|
201
|
+
* }),
|
|
202
|
+
* });
|
|
203
|
+
*
|
|
204
|
+
* dimensions = craftUse(state(
|
|
205
|
+
* { width: window.innerWidth, height: window.innerHeight },
|
|
206
|
+
* ({ set }) => ({
|
|
207
|
+
* // State updates automatically whenever resizeSource emits
|
|
208
|
+
* trackResize: afterRecomputation(this.resizeSource, (data) => {
|
|
209
|
+
* set(data);
|
|
210
|
+
* }),
|
|
211
|
+
* }),
|
|
212
|
+
* ));
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* Custom DOM event
|
|
218
|
+
* ```ts
|
|
219
|
+
* @Component({
|
|
220
|
+
* selector: 'app-custom-events',
|
|
221
|
+
* template: '<div></div>',
|
|
222
|
+
* providers: [provideCustomEventsStore()],
|
|
223
|
+
* })
|
|
224
|
+
* export class CustomEventsComponent {
|
|
225
|
+
* private readonly _elementRef = inject(ElementRef<HTMLElement>);
|
|
226
|
+
* store = CustomEventsStore();
|
|
227
|
+
*
|
|
228
|
+
* triggerCustomEvent() {
|
|
229
|
+
* const event = new CustomEvent('custom-event', {
|
|
230
|
+
* detail: { data: 'Hello from custom event' },
|
|
231
|
+
* });
|
|
232
|
+
* this._elementRef.nativeElement.dispatchEvent(event);
|
|
233
|
+
* }
|
|
234
|
+
* }
|
|
235
|
+
*
|
|
236
|
+
* const { CustomEventsStore, provideCustomEventsStore } = craftService(
|
|
237
|
+
* { name: 'CustomEventsStore', providedIn: 'toProvide' },
|
|
238
|
+
* function* () {
|
|
239
|
+
* const hostElement = inject(ElementRef<HTMLElement>).nativeElement;
|
|
240
|
+
* const customEventSource = sourceFromEvent<CustomEvent<{ data: string }>>(
|
|
241
|
+
* hostElement,
|
|
242
|
+
* 'custom-event',
|
|
243
|
+
* {
|
|
244
|
+
* computedValue: (event) => event.detail.data,
|
|
245
|
+
* },
|
|
246
|
+
* );
|
|
247
|
+
*
|
|
248
|
+
* const handleCustomEvent = yield* asyncProcess({
|
|
249
|
+
* method: afterRecomputation(customEventSource, (data) => data),
|
|
250
|
+
* loader: async ({ params }) => {
|
|
251
|
+
* console.log('Custom event data:', params);
|
|
252
|
+
* return { processed: true };
|
|
253
|
+
* },
|
|
254
|
+
* });
|
|
255
|
+
*
|
|
256
|
+
* return { customEventSource, handleCustomEvent };
|
|
257
|
+
* },
|
|
258
|
+
* );
|
|
259
|
+
* ```
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* Manual disposal for dynamic elements
|
|
263
|
+
* ```ts
|
|
264
|
+
* @Component({
|
|
265
|
+
* selector: 'app-dynamic',
|
|
266
|
+
* template: '...',
|
|
267
|
+
* })
|
|
268
|
+
* export class DynamicComponent {
|
|
269
|
+
* private clickSource?: SourceFromEvent<MouseEvent>;
|
|
270
|
+
*
|
|
271
|
+
* attachListener(element: HTMLElement) {
|
|
272
|
+
* // Remove previous listener if exists
|
|
273
|
+
* this.clickSource?.dispose();
|
|
274
|
+
*
|
|
275
|
+
* // Attach to new element
|
|
276
|
+
* this.clickSource = sourceFromEvent<MouseEvent>(element, 'click');
|
|
277
|
+
*
|
|
278
|
+
* // Use in store
|
|
279
|
+
* // ...
|
|
280
|
+
* }
|
|
281
|
+
*
|
|
282
|
+
* detachListener() {
|
|
283
|
+
* // Manually remove listener before component destruction
|
|
284
|
+
* this.clickSource?.dispose();
|
|
285
|
+
* this.clickSource = undefined;
|
|
286
|
+
* }
|
|
287
|
+
* }
|
|
288
|
+
* ```
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* Multiple event sources for keyboard shortcuts
|
|
292
|
+
* ```ts
|
|
293
|
+
* @Component({
|
|
294
|
+
* selector: 'app-shortcuts',
|
|
295
|
+
* template: '...',
|
|
296
|
+
* providers: [provideShortcutsStore()],
|
|
297
|
+
* })
|
|
298
|
+
* export class ShortcutsComponent {
|
|
299
|
+
* store = ShortcutsStore();
|
|
300
|
+
* }
|
|
301
|
+
*
|
|
302
|
+
* const { ShortcutsStore, provideShortcutsStore } = craftService(
|
|
303
|
+
* { name: 'ShortcutsStore', providedIn: 'toProvide' },
|
|
304
|
+
* function* () {
|
|
305
|
+
* const keydownSource = sourceFromEvent(document, 'keydown', {
|
|
306
|
+
* computedValue: (event: KeyboardEvent) => ({
|
|
307
|
+
* key: event.key,
|
|
308
|
+
* ctrlKey: event.ctrlKey,
|
|
309
|
+
* shiftKey: event.shiftKey,
|
|
310
|
+
* altKey: event.altKey,
|
|
311
|
+
* }),
|
|
312
|
+
* });
|
|
313
|
+
*
|
|
314
|
+
* const handleShortcut = yield* asyncProcess({
|
|
315
|
+
* method: afterRecomputation(keydownSource, (data) => data),
|
|
316
|
+
* loader: async ({ params }) => {
|
|
317
|
+
* // Handle Ctrl+S
|
|
318
|
+
* if (params.ctrlKey && params.key === 's') {
|
|
319
|
+
* // Save action
|
|
320
|
+
* return { action: 'save' };
|
|
321
|
+
* }
|
|
322
|
+
* // Handle Ctrl+Z
|
|
323
|
+
* if (params.ctrlKey && params.key === 'z') {
|
|
324
|
+
* // Undo action
|
|
325
|
+
* return { action: 'undo' };
|
|
326
|
+
* }
|
|
327
|
+
* return null;
|
|
328
|
+
* },
|
|
329
|
+
* });
|
|
330
|
+
*
|
|
331
|
+
* return { keydownSource, handleShortcut };
|
|
332
|
+
* },
|
|
333
|
+
* );
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
export declare function sourceFromEvent<T>(target: EventTarget, eventName: string, options?: {
|
|
337
|
+
event?: boolean | AddEventListenerOptions;
|
|
338
|
+
computedValue?: never;
|
|
339
|
+
source: {
|
|
340
|
+
equal?: ValueEqualityFn<NoInfer<T> | undefined>;
|
|
341
|
+
};
|
|
342
|
+
}): SourceFromEvent<T>;
|
|
343
|
+
export declare function sourceFromEvent<T, ComputedValue>(target: EventTarget, eventName: string, options?: {
|
|
344
|
+
event?: boolean | AddEventListenerOptions;
|
|
345
|
+
computedValue: (event: T) => ComputedValue;
|
|
346
|
+
source?: {
|
|
347
|
+
equal?: ValueEqualityFn<NoInfer<T> | undefined>;
|
|
348
|
+
};
|
|
349
|
+
}): SourceFromEvent<ComputedValue>;
|
|
350
|
+
//# sourceMappingURL=source-from-event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-from-event.d.ts","sourceRoot":"","sources":["../../../../../libs/core/src/lib/source-from-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAgB,MAAM,iBAAiB,CAAC;AAE7D,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyUG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,OAAO,GAAG,uBAAuB,CAAC;IAC1C,aAAa,CAAC,EAAE,KAAK,CAAC;IACtB,MAAM,EAAE;QACN,KAAK,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;KACjD,CAAC;CACH,GACA,eAAe,CAAC,CAAC,CAAC,CAAC;AACtB,wBAAgB,eAAe,CAAC,CAAC,EAAE,aAAa,EAC9C,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,OAAO,GAAG,uBAAuB,CAAC;IAC1C,aAAa,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,aAAa,CAAC;IAC3C,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;KACjD,CAAC;CACH,GACA,eAAe,CAAC,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { assertInInjectionContext, DestroyRef, inject, } from './host/craft-compat';
|
|
2
|
+
import { signalSource } from './signal-source';
|
|
3
|
+
export function sourceFromEvent(target, eventName, options) {
|
|
4
|
+
assertInInjectionContext(sourceFromEvent);
|
|
5
|
+
const eventSignalSource = signalSource(eventName, options?.source);
|
|
6
|
+
const listener = (event) => {
|
|
7
|
+
if (options?.computedValue) {
|
|
8
|
+
const computed = options.computedValue(event);
|
|
9
|
+
eventSignalSource.set(computed);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
eventSignalSource.set(event);
|
|
13
|
+
};
|
|
14
|
+
target.addEventListener(eventName, listener, options?.event);
|
|
15
|
+
const destroyRef = inject(DestroyRef);
|
|
16
|
+
const dispose = () => {
|
|
17
|
+
target.removeEventListener(eventName, listener, options?.event);
|
|
18
|
+
};
|
|
19
|
+
destroyRef.onDestroy(() => {
|
|
20
|
+
dispose();
|
|
21
|
+
});
|
|
22
|
+
return Object.assign(eventSignalSource, {
|
|
23
|
+
dispose,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=source-from-event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-from-event.js","sourceRoot":"","sources":["../../../../../libs/core/src/lib/source-from-event.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,UAAU,EACV,MAAM,GAEP,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAgB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAsW7D,MAAM,UAAU,eAAe,CAC7B,MAAmB,EACnB,SAAiB,EACjB,OAMC;IAED,wBAAwB,CAAC,eAAe,CAAC,CAAC;IAC1C,MAAM,iBAAiB,GAAG,YAAY,CAAU,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAE5E,MAAM,QAAQ,GAAG,CAAC,KAAY,EAAE,EAAE;QAChC,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC9C,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QACD,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAE7D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC,CAAC;IAEF,UAAU,CAAC,SAAS,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE;QACtC,OAAO;KACR,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n assertInInjectionContext,\n DestroyRef,\n inject,\n ValueEqualityFn,\n} from './host/craft-compat';\nimport { SignalSource, signalSource } from './signal-source';\n\nexport type SourceFromEvent<T> = SignalSource<T> & {\n dispose: () => void;\n};\n\n/**\n * Creates a source from DOM events with automatic cleanup on component destruction.\n *\n * This function bridges DOM events with craft-ts's reactive system by:\n * - Converting native DOM events to source emissions\n * - Automatically removing event listeners on component destruction\n * - Supporting optional event payload transformation\n * - Providing manual disposal capability\n * - Enabling event-driven query/mutation triggering\n *\n * @remarks\n * **Automatic Cleanup:**\n * - Event listeners are automatically removed when the injection context is destroyed\n * - Uses Angular's `DestroyRef` for lifecycle management\n * - Manual cleanup available via `dispose()` method\n * - Prevents memory leaks from dangling event listeners\n *\n * **Use Cases:**\n * - **User interactions**: Click, input, scroll, keyboard events\n * - **Window events**: Resize, scroll, focus, online/offline\n * - **Document events**: Visibility changes, custom events\n * - **Media events**: Video/audio play, pause, ended\n * - **Form events**: Submit, change, input\n * - **Custom events**: Application-specific DOM events\n *\n * **Event Transformation:**\n * - Without `computedValue`: Emits the raw event object\n * - With `computedValue`: Transforms event before emission\n * - Useful for extracting specific event properties\n * - Reduces payload size and improves type safety\n *\n * **Integration with Stores:**\n * - Use source in queries/mutations via `afterRecomputation()`\n * - Trigger async operations on DOM events\n * - Coordinate multiple components via event sources\n *\n * **Injection Context:**\n * - Must be called within Angular injection context\n * - Typically called in component constructor or class fields\n * - Uses `assertInInjectionContext()` for safety\n *\n * @template T - The type of the event object\n * @template ComputedValue - The type after optional transformation\n *\n * @param target - The DOM element or event target to listen to.\n * Can be any EventTarget (HTMLElement, Window, Document, etc.)\n *\n * @param eventName - The name of the event to listen for.\n * Standard DOM event names: 'click', 'input', 'scroll', etc.\n *\n * @param options - Optional configuration:\n * - `event`: Event listener options (capture, passive, once, etc.)\n * - `computedValue`: Function to transform event before emission\n * - `source`: Source options (equal)\n *\n * @returns A source that emits on DOM events with:\n * - All standard source capabilities (set, preserveLastValue)\n * - `dispose()`: Method to manually remove event listener\n * - Automatic cleanup on component destruction\n *\n * @example\n * Basic click event source\n * ```ts\n * @Component({\n * selector: 'app-clicker',\n * template: '<button>Click me</button>',\n * providers: [provideClickTrackerStore()],\n * })\n * export class ClickerComponent {\n * store = ClickTrackerStore();\n *\n * // Mutation executes automatically on click\n * }\n *\n * const { ClickTrackerStore, provideClickTrackerStore } = craftService(\n * { name: 'ClickTrackerStore', providedIn: 'toProvide' },\n * function* () {\n * const hostElement = inject(ElementRef<HTMLElement>).nativeElement;\n * const clickSource = sourceFromEvent<MouseEvent>(hostElement, 'click');\n *\n * const trackClick = yield* mutation({\n * method: afterRecomputation(clickSource, (event) => ({\n * x: event.clientX,\n * y: event.clientY,\n * })),\n * loader: async ({ params }) => {\n * await fetch('/api/track-click', {\n * method: 'POST',\n * body: JSON.stringify(params),\n * });\n * return { tracked: true };\n * },\n * });\n *\n * return { clickSource, trackClick };\n * },\n * );\n * ```\n *\n * @example\n * Window scroll event with transformation\n * ```ts\n * @Component({\n * selector: 'app-infinite-scroll',\n * template: '...',\n * providers: [provideInfiniteScrollStore()],\n * })\n * export class InfiniteScrollComponent {\n * store = InfiniteScrollStore();\n * }\n *\n * const { InfiniteScrollStore, provideInfiniteScrollStore } = craftService(\n * { name: 'InfiniteScrollStore', providedIn: 'toProvide' },\n * function* () {\n * const scrollSource = sourceFromEvent(window, 'scroll', {\n * computedValue: () => ({\n * scrollY: window.scrollY,\n * scrollHeight: document.documentElement.scrollHeight,\n * clientHeight: window.innerHeight,\n * }),\n * event: { passive: true }, // Optimize performance\n * });\n *\n * const checkLoadMore = yield* asyncProcess({\n * method: afterRecomputation(scrollSource, (data) => data),\n * loader: async ({ params }) => {\n * const { scrollY, scrollHeight, clientHeight } = params;\n * const nearBottom = scrollY + clientHeight >= scrollHeight - 100;\n *\n * if (nearBottom) {\n * // Load more data\n * const response = await fetch('/api/load-more');\n * return response.json();\n * }\n * return null;\n * },\n * });\n *\n * return { scrollSource, checkLoadMore };\n * },\n * );\n * ```\n *\n * @example\n * Form input event for real-time validation\n * ```ts\n * @Component({\n * selector: 'app-search',\n * template: '<input type=\"text\" placeholder=\"Search...\" />',\n * providers: [provideSearchStore()],\n * })\n * export class SearchComponent {\n * store = SearchStore();\n *\n * // Query executes on input changes\n * }\n *\n * const { SearchStore, provideSearchStore } = craftService(\n * { name: 'SearchStore', providedIn: 'toProvide' },\n * function* () {\n * const hostElement = inject(ElementRef<HTMLElement>).nativeElement;\n * const inputSource = sourceFromEvent(hostElement, 'input', {\n * computedValue: (event: Event) => {\n * const target = event.target as HTMLInputElement;\n * return target.value;\n * },\n * });\n *\n * const results = yield* query({\n * method: afterRecomputation(inputSource, (term) => term),\n * loader: async ({ params }) => {\n * if (params.length < 3) return [];\n *\n * const response = await fetch(`/api/search?q=${params}`);\n * return response.json();\n * },\n * });\n *\n * return { inputSource, results };\n * },\n * );\n * ```\n *\n * @example\n * Window resize event updating a state\n * ```ts\n * @Component({\n * selector: 'app-responsive',\n * template: '...',\n * })\n * export class ResponsiveComponent {\n * resizeSource = sourceFromEvent(window, 'resize', {\n * computedValue: () => ({\n * width: window.innerWidth,\n * height: window.innerHeight,\n * }),\n * });\n *\n * dimensions = craftUse(state(\n * { width: window.innerWidth, height: window.innerHeight },\n * ({ set }) => ({\n * // State updates automatically whenever resizeSource emits\n * trackResize: afterRecomputation(this.resizeSource, (data) => {\n * set(data);\n * }),\n * }),\n * ));\n * }\n * ```\n *\n * @example\n * Custom DOM event\n * ```ts\n * @Component({\n * selector: 'app-custom-events',\n * template: '<div></div>',\n * providers: [provideCustomEventsStore()],\n * })\n * export class CustomEventsComponent {\n * private readonly _elementRef = inject(ElementRef<HTMLElement>);\n * store = CustomEventsStore();\n *\n * triggerCustomEvent() {\n * const event = new CustomEvent('custom-event', {\n * detail: { data: 'Hello from custom event' },\n * });\n * this._elementRef.nativeElement.dispatchEvent(event);\n * }\n * }\n *\n * const { CustomEventsStore, provideCustomEventsStore } = craftService(\n * { name: 'CustomEventsStore', providedIn: 'toProvide' },\n * function* () {\n * const hostElement = inject(ElementRef<HTMLElement>).nativeElement;\n * const customEventSource = sourceFromEvent<CustomEvent<{ data: string }>>(\n * hostElement,\n * 'custom-event',\n * {\n * computedValue: (event) => event.detail.data,\n * },\n * );\n *\n * const handleCustomEvent = yield* asyncProcess({\n * method: afterRecomputation(customEventSource, (data) => data),\n * loader: async ({ params }) => {\n * console.log('Custom event data:', params);\n * return { processed: true };\n * },\n * });\n *\n * return { customEventSource, handleCustomEvent };\n * },\n * );\n * ```\n *\n * @example\n * Manual disposal for dynamic elements\n * ```ts\n * @Component({\n * selector: 'app-dynamic',\n * template: '...',\n * })\n * export class DynamicComponent {\n * private clickSource?: SourceFromEvent<MouseEvent>;\n *\n * attachListener(element: HTMLElement) {\n * // Remove previous listener if exists\n * this.clickSource?.dispose();\n *\n * // Attach to new element\n * this.clickSource = sourceFromEvent<MouseEvent>(element, 'click');\n *\n * // Use in store\n * // ...\n * }\n *\n * detachListener() {\n * // Manually remove listener before component destruction\n * this.clickSource?.dispose();\n * this.clickSource = undefined;\n * }\n * }\n * ```\n *\n * @example\n * Multiple event sources for keyboard shortcuts\n * ```ts\n * @Component({\n * selector: 'app-shortcuts',\n * template: '...',\n * providers: [provideShortcutsStore()],\n * })\n * export class ShortcutsComponent {\n * store = ShortcutsStore();\n * }\n *\n * const { ShortcutsStore, provideShortcutsStore } = craftService(\n * { name: 'ShortcutsStore', providedIn: 'toProvide' },\n * function* () {\n * const keydownSource = sourceFromEvent(document, 'keydown', {\n * computedValue: (event: KeyboardEvent) => ({\n * key: event.key,\n * ctrlKey: event.ctrlKey,\n * shiftKey: event.shiftKey,\n * altKey: event.altKey,\n * }),\n * });\n *\n * const handleShortcut = yield* asyncProcess({\n * method: afterRecomputation(keydownSource, (data) => data),\n * loader: async ({ params }) => {\n * // Handle Ctrl+S\n * if (params.ctrlKey && params.key === 's') {\n * // Save action\n * return { action: 'save' };\n * }\n * // Handle Ctrl+Z\n * if (params.ctrlKey && params.key === 'z') {\n * // Undo action\n * return { action: 'undo' };\n * }\n * return null;\n * },\n * });\n *\n * return { keydownSource, handleShortcut };\n * },\n * );\n * ```\n */\nexport function sourceFromEvent<T>(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue?: never;\n source: {\n equal?: ValueEqualityFn<NoInfer<T> | undefined>;\n };\n },\n): SourceFromEvent<T>;\nexport function sourceFromEvent<T, ComputedValue>(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue: (event: T) => ComputedValue;\n source?: {\n equal?: ValueEqualityFn<NoInfer<T> | undefined>;\n };\n },\n): SourceFromEvent<ComputedValue>;\nexport function sourceFromEvent(\n target: EventTarget,\n eventName: string,\n options?: {\n event?: boolean | AddEventListenerOptions;\n computedValue?: (event: Event) => unknown;\n source?: {\n equal?: ValueEqualityFn<NoInfer<unknown> | undefined>;\n };\n },\n): SourceFromEvent<unknown> {\n assertInInjectionContext(sourceFromEvent);\n const eventSignalSource = signalSource<unknown>(eventName, options?.source);\n\n const listener = (event: Event) => {\n if (options?.computedValue) {\n const computed = options.computedValue(event);\n eventSignalSource.set(computed);\n return;\n }\n eventSignalSource.set(event);\n };\n\n target.addEventListener(eventName, listener, options?.event);\n\n const destroyRef = inject(DestroyRef);\n\n const dispose = () => {\n target.removeEventListener(eventName, listener, options?.event);\n };\n\n destroyRef.onDestroy(() => {\n dispose();\n });\n\n return Object.assign(eventSignalSource, {\n dispose,\n });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stacked-source.d.ts","sourceRoot":"","sources":["../../../../../libs/core/src/lib/stacked-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAU,MAAM,qBAAqB,CAAC;AAEnE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,GAAG;IACrD,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CACzB,CAAC;AAGF,wBAAgB,aAAa,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,CA8BjD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { linkedSignal, signal } from './host/craft-compat';
|
|
2
|
+
// ! this algo only works with object
|
|
3
|
+
export function stackedSource() {
|
|
4
|
+
const stack = [];
|
|
5
|
+
const s2 = signal(undefined);
|
|
6
|
+
const l = linkedSignal({
|
|
7
|
+
source: s2,
|
|
8
|
+
computation: (current, previousData) => {
|
|
9
|
+
if (!previousData) {
|
|
10
|
+
stack.length = 0;
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const result = [...stack];
|
|
14
|
+
stack.length = 0;
|
|
15
|
+
return result;
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
const set = (value) => {
|
|
19
|
+
console.log('custom set', value);
|
|
20
|
+
stack.push(value);
|
|
21
|
+
console.log('stack', stack);
|
|
22
|
+
s2.set(value);
|
|
23
|
+
return;
|
|
24
|
+
};
|
|
25
|
+
return Object.assign(l, {
|
|
26
|
+
set,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=stacked-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stacked-source.js","sourceRoot":"","sources":["../../../../../libs/core/src/lib/stacked-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAU,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAMnE,qCAAqC;AACrC,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,MAAM,CAAgB,SAAS,CAAC,CAAC;IAE5C,MAAM,CAAC,GAAG,YAAY,CAAC;QACrB,MAAM,EAAE,EAAE;QACV,WAAW,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE;YACrC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;gBACjB,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;YAC1B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACjB,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,CAAC,KAAQ,EAAE,EAAE;QACvB,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAE5B,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACd,OAAO;IACT,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;QACtB,GAAG;KACJ,CAAmB,CAAC;AACvB,CAAC","sourcesContent":["import { linkedSignal, Signal, signal } from './host/craft-compat';\n\nexport type StackSource<T> = Signal<T[] | undefined> & {\n set: (value: T) => void;\n};\n\n// ! this algo only works with object\nexport function stackedSource<T>(): StackSource<T> {\n const stack: unknown[] = [];\n const s2 = signal<T | undefined>(undefined);\n\n const l = linkedSignal({\n source: s2,\n computation: (current, previousData) => {\n if (!previousData) {\n stack.length = 0;\n return undefined;\n }\n\n const result = [...stack];\n stack.length = 0;\n return result;\n },\n });\n\n const set = (value: T) => {\n console.log('custom set', value);\n stack.push(value);\n console.log('stack', stack);\n\n s2.set(value);\n return;\n };\n\n return Object.assign(l, {\n set,\n }) as StackSource<T>;\n}\n"]}
|