@arcgis/lumina 4.33.0-next.13 → 4.33.0-next.132

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.
Files changed (57) hide show
  1. package/dist/Controller-BQOv8BAL.js +587 -0
  2. package/dist/LitElement.d.ts +56 -45
  3. package/dist/config.d.ts +7 -9
  4. package/dist/config.js +18 -8
  5. package/dist/context.d.ts +14 -4
  6. package/dist/controllers/Controller.d.ts +147 -0
  7. package/dist/controllers/ControllerInternals.d.ts +53 -0
  8. package/dist/controllers/ControllerManager.d.ts +87 -0
  9. package/dist/controllers/accessor/index.d.ts +2 -0
  10. package/dist/controllers/accessor/index.js +225 -0
  11. package/dist/controllers/accessor/reEmitEvent.d.ts +10 -0
  12. package/dist/controllers/accessor/useAccessor.d.ts +71 -0
  13. package/dist/controllers/functional.d.ts +19 -0
  14. package/dist/controllers/index.d.ts +24 -0
  15. package/dist/controllers/index.js +270 -0
  16. package/dist/controllers/load.d.ts +6 -0
  17. package/dist/controllers/proxyExports.d.ts +27 -0
  18. package/dist/controllers/tests/autoDestroyMock.d.ts +5 -0
  19. package/dist/controllers/tests/utils.d.ts +1 -0
  20. package/dist/controllers/toFunction.d.ts +8 -0
  21. package/dist/controllers/trackKey.d.ts +8 -0
  22. package/dist/controllers/trackPropKey.d.ts +21 -0
  23. package/dist/controllers/trackPropertyKey.d.ts +29 -0
  24. package/dist/controllers/types.d.ts +187 -0
  25. package/dist/controllers/useDirection.d.ts +11 -0
  26. package/dist/controllers/useMedia.d.ts +8 -0
  27. package/dist/controllers/usePropertyChange.d.ts +14 -0
  28. package/dist/controllers/useT9n.d.ts +48 -0
  29. package/dist/controllers/useWatchAttributes.d.ts +7 -0
  30. package/dist/controllers/utils.d.ts +12 -0
  31. package/dist/createEvent.d.ts +8 -3
  32. package/dist/decorators.d.ts +2 -2
  33. package/dist/devOnlyDetectIncorrectLazyUsages.d.ts +1 -1
  34. package/dist/hmrSupport.d.ts +1 -1
  35. package/dist/hmrSupport.js +22 -28
  36. package/dist/index.d.ts +17 -16
  37. package/dist/index.js +415 -192
  38. package/dist/jsx/baseTypes.d.ts +13 -9
  39. package/dist/jsx/directives.d.ts +25 -7
  40. package/dist/jsx/generatedTypes.d.ts +420 -90
  41. package/dist/jsx/types.d.ts +5 -32
  42. package/dist/lazyLoad-ByH-FaBP.js +403 -0
  43. package/dist/lazyLoad.d.ts +27 -72
  44. package/dist/lifecycleSupport.d.ts +2 -2
  45. package/dist/makeRuntime.d.ts +131 -0
  46. package/dist/proxyExports-Cdzj7WL_.js +60 -0
  47. package/dist/render.d.ts +5 -0
  48. package/dist/runtime.d.ts +4 -107
  49. package/dist/stencilSsrCompatibility/index.d.ts +2 -6
  50. package/dist/stencilSsrCompatibility/index.js +2 -3
  51. package/dist/typings/importMeta.d.ts +2 -2
  52. package/dist/utils.d.ts +8 -0
  53. package/dist/wrappersUtils.d.ts +13 -1
  54. package/package.json +7 -6
  55. package/dist/chunk-NO7HOBNA.js +0 -421
  56. package/dist/chunk-PGHUBTOM.js +0 -21
  57. package/dist/wrappersUtils.test.d.ts +0 -1
@@ -0,0 +1,225 @@
1
+ import { G as GenericController, l as trackPropKey, t as trackKey, r as retrieveComponent, f as createEventFactory } from "../../Controller-BQOv8BAL.js";
2
+ import { p as proxyExports } from "../../proxyExports-Cdzj7WL_.js";
3
+ import { isEsriInternalEnv } from "@arcgis/components-utils";
4
+ import { watch, on } from "@arcgis/core/core/reactiveUtils.js";
5
+ import { createObservable, createTrackingTarget, runTracked, trackAccess } from "@arcgis/core/applications/Components/reactiveUtils.js";
6
+ const makeAccessorController = (createInstance, _options) => (component) => proxy(component, createInstance);
7
+ class AccessorController extends GenericController {
8
+ constructor(component, createInstance) {
9
+ super(component);
10
+ this.Y = /* @__PURE__ */ new Map();
11
+ this.#exportsObservable = createObservable();
12
+ const that = this;
13
+ that.#createInstance = createInstance;
14
+ that.Z();
15
+ component.manager.A = createTrackingTarget;
16
+ component.manager.B = runTracked;
17
+ that.setProvisionalExports(
18
+ makeBinderProxy(
19
+ component,
20
+ new WeakRef(that),
21
+ component.M.length - 1,
22
+ that.instance,
23
+ that.Y
24
+ ),
25
+ false
26
+ );
27
+ trackPropKey(
28
+ component,
29
+ (resolved) => {
30
+ if (resolved) {
31
+ const handle = watch(
32
+ // If the property to which controller is assigned is public, the user may
33
+ // manually create an accessor instance and assign it to this property
34
+ // We pick it up and replace our created accessor instance with user's.
35
+ () => component[resolved],
36
+ (newInstance) => {
37
+ if (newInstance === that.instance) {
38
+ return;
39
+ }
40
+ const oldInstance = that.instance;
41
+ that.exports = newInstance;
42
+ that.instance = newInstance;
43
+ that.Y.forEach(
44
+ (propName, propertyName) => component.requestUpdate(propName, oldInstance[propertyName])
45
+ );
46
+ if (that.#isInstanceOwner) {
47
+ oldInstance.destroy();
48
+ }
49
+ that.#isInstanceOwner = false;
50
+ },
51
+ { sync: true }
52
+ );
53
+ that.onDestroy(handle.remove);
54
+ }
55
+ },
56
+ that.exports
57
+ );
58
+ }
59
+ #isInstanceOwner;
60
+ #exportsObservable;
61
+ #createInstance;
62
+ get exports() {
63
+ trackAccess(this.#exportsObservable);
64
+ return super.exports;
65
+ }
66
+ set exports(value) {
67
+ super.exports = value;
68
+ this.#exportsObservable.notify();
69
+ }
70
+ /** @private */
71
+ Z() {
72
+ const that = this;
73
+ that.instance = "prototype" in that.#createInstance && "declaredClass" in that.#createInstance.prototype ? new that.#createInstance() : that.#createInstance();
74
+ that.#isInstanceOwner = true;
75
+ }
76
+ hostConnected() {
77
+ this.exports = this.instance;
78
+ }
79
+ // FEATURE: is there a way to detect that accessor does not need to be destroyed?
80
+ // Is it possible to write accessors that don't need to be destroyed?
81
+ hostDestroy() {
82
+ if (this.#isInstanceOwner) {
83
+ this.instance.destroy?.();
84
+ }
85
+ }
86
+ }
87
+ const proxy = proxyExports(AccessorController);
88
+ const makeBinderProxy = (component, accessorControllerRef, accessorControllerIndex, instance, boundProperties) => new Proxy(instance, {
89
+ get: (target, propertyName) => {
90
+ const value = target[propertyName];
91
+ if (
92
+ // Possibly called by the JS engine
93
+ typeof propertyName === "symbol" || // Already bound?
94
+ boundProperties.has(propertyName)
95
+ ) {
96
+ return value;
97
+ }
98
+ return trackKey(
99
+ component,
100
+ (resolved) => {
101
+ if (resolved !== void 0) {
102
+ const propName = resolved.key;
103
+ boundProperties.set(propertyName, propName);
104
+ const descriptor = component.constructor.getPropertyOptions(
105
+ propName
106
+ );
107
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
108
+ if (!(propertyName in instance)) {
109
+ throw new Error(`"${propertyName}" does not exist on the accessor instance`);
110
+ }
111
+ const accessorController = component.M[accessorControllerIndex];
112
+ if (descriptor.i !== void 0 && descriptor.i !== accessorControllerIndex) {
113
+ console.error(component.M[descriptor.i], accessorController);
114
+ throw Error(
115
+ `Expected property "${propName}" to be bound to the controller at index ${descriptor.i}, but tried to bind it to a controller at index ${accessorControllerIndex}. Double check whether you are calling useAccessor() conditionally in a way that is not supported.`
116
+ );
117
+ }
118
+ if (accessorController !== accessorControllerRef.deref()) {
119
+ console.error(accessorController);
120
+ throw Error(
121
+ `Expected controller at index ${accessorControllerIndex} to be instance of useAccessor but it is not.`
122
+ );
123
+ }
124
+ const isFlippingBoolean = resolved.key.toLowerCase().includes("disable");
125
+ const collidesWithNativeProp = propertyName in HTMLElement.prototype;
126
+ const collidesWithCustomProp = accessorControllerRef.deref().constructor.devOnly$allowedPropNameMismatches?.has(propName) === true;
127
+ if (resolved.key !== propertyName && !collidesWithNativeProp && !collidesWithCustomProp && !isFlippingBoolean) {
128
+ throw new Error(
129
+ `Tried to bind "${resolved?.key}" property to "${propertyName.toString()}" - property names must match`
130
+ );
131
+ }
132
+ if (!resolved.isReactive) {
133
+ throw new Error(
134
+ `For two-way binding with Accessor to work, the property on your component must have @property() or @state() decorator. "${propertyName.toString()}" has neither`
135
+ );
136
+ }
137
+ }
138
+ const shouldFlipBoolean = propertyName !== propName && propName.toLowerCase().includes("disable");
139
+ watchBoundProperty(accessorControllerRef, descriptor, propertyName, propName, shouldFlipBoolean);
140
+ if (descriptor.i === void 0) {
141
+ bindPropToProperty(descriptor, accessorControllerIndex, propertyName, shouldFlipBoolean);
142
+ }
143
+ }
144
+ },
145
+ value
146
+ );
147
+ },
148
+ set(_target, propertyName, newValue) {
149
+ if (boundProperties.has(propertyName) || // But some properties may be never bound, yet set in the constructor - let them through
150
+ newValue !== (instance[propertyName] ?? void 0)) {
151
+ instance[propertyName] = newValue;
152
+ }
153
+ return true;
154
+ }
155
+ });
156
+ const watchBoundProperty = (controllerRef, descriptor, propertyName, propName, shouldFlipBoolean, _handle) => _handle = watch(
157
+ () => {
158
+ const controller = controllerRef.deref();
159
+ return controller === void 0 || controller.component.manager.destroyed ? (
160
+ // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
161
+ _handle = _handle.remove()
162
+ ) : controller.exports[propertyName];
163
+ },
164
+ (_, oldValue) => {
165
+ if (!_handle) {
166
+ return;
167
+ }
168
+ const component = controllerRef.deref().component;
169
+ component?.requestUpdate(propName, shouldFlipBoolean ? !oldValue : oldValue);
170
+ descriptor.c = false;
171
+ },
172
+ // At present, since useAccessor initializes the Accessor instance without
173
+ // any properties, it assumes that there is no need to do initial sync of
174
+ // accessor properties to the component, especially since the component
175
+ // setter always gets the newest value from the Accessor instance anyway.
176
+ // We might wish to change that if view model is shared between multiple
177
+ // components and has default value for some property. Even then, this issue
178
+ // will only manifest itself in default value not being reflected to
179
+ // attribute (). If fixing above becomes important, can do so by adding
180
+ // `initial: true` here and updating the above code to only call .notify()
181
+ // if hasChanged returns true (see reference implementation in
182
+ // _handleInstanceChanged). Not doing so yet as it is an edge case that is
183
+ // easy to work around and proper fix will add overhead to the startup of
184
+ // each component.
185
+ { sync: true }
186
+ );
187
+ const bindPropToProperty = (descriptor, accessorControllerIndex, propertyName, shouldFlipBoolean) => {
188
+ descriptor.d.get = function() {
189
+ const value = this.M[accessorControllerIndex]?.exports[propertyName];
190
+ return shouldFlipBoolean ? !value : value;
191
+ };
192
+ descriptor.d.set = function(newValue) {
193
+ this.M[accessorControllerIndex].exports[propertyName] = shouldFlipBoolean ? !newValue : newValue;
194
+ };
195
+ };
196
+ const getAccessorControllerBoundProperties = (controller) => controller.Y;
197
+ const reCreateAccessor = (instance, component) => {
198
+ const accessorController = component.manager.useRefSync(instance);
199
+ accessorController?.hostDestroy();
200
+ accessorController?.Z();
201
+ accessorController?.hostConnected();
202
+ if (process.env.NODE_ENV !== "production" && accessorController === void 0) {
203
+ console.error("Unable to resolve the useAccessor controller from the provided value");
204
+ }
205
+ };
206
+ const reEmitEvent = (getEventedAccessor, eventName) => {
207
+ const component = retrieveComponent();
208
+ const manager = component.manager;
209
+ manager.onLoaded(() => manager.onLifecycle(() => on(getEventedAccessor, eventName, emitter.emit)));
210
+ const emitter = createEventFactory();
211
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
212
+ if (typeof emitter !== "object" || emitter === null || !("emit" in emitter) || typeof emitter.emit !== "function") {
213
+ throw new Error(`Expected to find $createEvent static property on Lumina's LitElement`);
214
+ }
215
+ }
216
+ return emitter;
217
+ };
218
+ export {
219
+ AccessorController,
220
+ getAccessorControllerBoundProperties,
221
+ makeAccessorController,
222
+ makeBinderProxy,
223
+ reCreateAccessor,
224
+ reEmitEvent
225
+ };
@@ -0,0 +1,10 @@
1
+ import { EventEmitter } from '../../createEvent';
2
+ /**
3
+ * Re-emit an event from the accessor instance on the component
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * arcgisGo = reEmitEvent<__esri.HomeViewModelGoEvent>(() => this.viewModel, "go");
8
+ * ```
9
+ */
10
+ export declare const reEmitEvent: <T>(getEventedAccessor: () => __esri.Evented, eventName: string) => EventEmitter<T>;
@@ -0,0 +1,71 @@
1
+ import { Controller, GenericController } from '../Controller';
2
+ import { LitElement } from '../../LitElement';
3
+ type Requires<Props, Accessor extends __esri.Accessor, OmitProps extends string = never> = LitElement & Omit<Pick<Accessor, keyof Accessor & keyof Props>, AlwaysOmit | OmitProps> & {
4
+ autoDestroyDisabled: boolean;
5
+ destroy: () => Promise<void>;
6
+ };
7
+ type AlwaysOmit = "addHandles" | "declaredClass" | "destroyed" | "hasHandles" | "initialized" | "removeHandles" | "set" | "watch";
8
+ /**
9
+ * Given an Accessor class, create a controller that will do two-way binding of
10
+ * props between the component and the Accessor.
11
+ *
12
+ * See https://qawebgis.esri.com/components/lumina/controllers/useAccessor for
13
+ * documentation & examples.
14
+ */
15
+ export declare const makeAccessorController: <Props, Accessor extends __esri.Accessor, OmitProps extends string = never>(createInstance: ((props?: Props) => Accessor) | (new (props?: Props) => Accessor), _options?: {
16
+ /**
17
+ * By default, to ensure that you didn't accidentally forget to bind any
18
+ * of the Accessor's properties on your component, every property that
19
+ * is accepted by the Accessor's constructor will be required to be bound
20
+ * on your component. If you do not wish to bind certain properties
21
+ * (or you wish to bind them but with a different type), you can omit
22
+ * them using this option.
23
+ *
24
+ * You can also bind the property to \@state rather than \@property if you
25
+ * wish to use it internally only:
26
+ * @example
27
+ * ```tsx
28
+ * \@State() timeZone = this.viewModel.timeZone;
29
+ * ```
30
+ *
31
+ * @remarks
32
+ * This option affects the TypeScript error checking only - it has
33
+ * no runtime impact. Thus, if you wish to save a few bytes in the
34
+ * bundle, rather than simply setting this property like
35
+ * `makeAccessorController(..., { omitProps: ["propName"] })`, you can
36
+ * set it like this:
37
+ * `makeAccessorController(..., {} as { omitProps: ["propName"] })`
38
+ */
39
+ omitProps: OmitProps[];
40
+ }) => (component: Requires<Props, Accessor, OmitProps>) => Accessor;
41
+ export declare class AccessorController<Props, Accessor extends __esri.Accessor, ExtraRequires = Record<never, never>> extends GenericController<Accessor, ExtraRequires & Requires<Props, Accessor>> {
42
+ #private;
43
+ protected instance: Accessor;
44
+ /**
45
+ * Use getAccessorControllerBoundProperties() helper to get access to this map
46
+ * @private
47
+ */
48
+ _boundAccessorProperties: Map<string & keyof Accessor, string>;
49
+ /**
50
+ * (development only) Allow these props to mismatch the name of the Accessor's
51
+ * property to avoid collisions
52
+ *
53
+ * @private
54
+ */
55
+ static devOnly$allowedPropNameMismatches?: ReadonlySet<string>;
56
+ get exports(): Accessor;
57
+ set exports(value: Accessor);
58
+ constructor(component: ExtraRequires & Requires<Props, Accessor>, createInstance: ((props?: Props) => Accessor) | (new (props?: Props) => Accessor));
59
+ /** @private */
60
+ _createAccessorInstance(): void;
61
+ hostConnected(): void;
62
+ hostDestroy(): void;
63
+ }
64
+ export declare const makeBinderProxy: (component: LitElement, accessorControllerRef: WeakRef<Pick<Controller<__esri.Accessor>, "component" | "exports"> & {
65
+ constructor: (typeof __esri.Accessor)["constructor"] & {
66
+ devOnly$allowedPropNameMismatches?: ReadonlySet<string>;
67
+ };
68
+ }>, accessorControllerIndex: number, instance: __esri.Accessor, boundProperties: Map<string, string>) => unknown;
69
+ export declare const getAccessorControllerBoundProperties: <Accessor extends __esri.Accessor>(controller: AccessorController<unknown, Accessor>) => Map<string & keyof Accessor, string>;
70
+ export declare const reCreateAccessor: (instance: __esri.Accessor, component: LitElement) => void;
71
+ export {};
@@ -0,0 +1,19 @@
1
+ import { LitElement } from '../LitElement';
2
+ import { GenericControllerType, Controller } from './Controller';
3
+ /**
4
+ * Controller is a function that takes a component instance and then can
5
+ * export some values to the component, or hook into component's lifecycle
6
+ *
7
+ * See controllers documentation for many example controllers and their usages
8
+ */
9
+ export declare const makeController: <Exports>(constructor: (component: LitElement, controller: Controller<Exports>) => Exports | Promise<Exports>) => Exports;
10
+ /**
11
+ * If your controller requires some specific properties to be present on the
12
+ * component, besides what's included in the LitElement, use
13
+ * makeGenericController
14
+ *
15
+ * When using a controller created using makeGenericController(), consumer must
16
+ * pass in "this" explicitly for proper type-checking. If controller was
17
+ * created using makeController(), that is not necessary
18
+ */
19
+ export declare const makeGenericController: <Exports, Component = LitElement>(constructor: (component: Component & LitElement, controller: GenericControllerType<Exports, Component>) => Exports | Promise<Exports>) => (component: Component & LitElement) => Exports;
@@ -0,0 +1,24 @@
1
+ import { EventEmitter as _EventEmitter } from '../createEvent';
2
+ export type { GenericControllerType } from './Controller';
3
+ export { Controller, GenericController } from './Controller';
4
+ export type { ControllerManager } from './ControllerManager';
5
+ export { retrieveComponent, bypassSetter, bypassReadOnly } from './ControllerInternals';
6
+ export { trackPropertyKey, keyTrackResolve } from './trackPropertyKey';
7
+ export { trackPropKey } from './trackPropKey';
8
+ export { trackKey } from './trackKey';
9
+ export { makeController, makeGenericController } from './functional';
10
+ export { useWatchAttributes } from './useWatchAttributes';
11
+ export { load } from './load';
12
+ export { proxyExports } from './proxyExports';
13
+ export { toFunction } from './toFunction';
14
+ export * from './types';
15
+ export { useMedia } from './useMedia';
16
+ export { useDirection } from './useDirection';
17
+ export type { UseT9n, T9nMeta } from './useT9n';
18
+ export { makeT9nController } from './useT9n';
19
+ export { usePropertyChange } from './usePropertyChange';
20
+ export { isController, getControllersCount } from './utils';
21
+ /**
22
+ * @deprecated import from "@arcgis/lumina" instead
23
+ */
24
+ export type EventEmitter<T = undefined> = _EventEmitter<T>;
@@ -0,0 +1,270 @@
1
+ import { C as Controller, s as setAmbientComponent, i as isPromise, d as setParentController, e as retrieveParentControllers, t as trackKey, r as retrieveComponent, f as createEventFactory } from "../Controller-BQOv8BAL.js";
2
+ import { G, h, g, c, n, m, k, l, j } from "../Controller-BQOv8BAL.js";
3
+ import { p as proxyExports } from "../proxyExports-Cdzj7WL_.js";
4
+ import { isServer } from "lit";
5
+ import { observeAncestorsMutation, isEsriInternalEnv, getElementAttribute, getElementLocales, startLocaleObserver } from "@arcgis/components-utils";
6
+ const makeController = (constructor) => proxy(void 0, constructor);
7
+ const makeGenericController = (constructor) => (component) => proxy(
8
+ component,
9
+ /**
10
+ * GenericController is identical to Controller, in all except for typing.
11
+ * So dying a type-cast here so as not to needlessly add one more object
12
+ * to the prototype chain
13
+ */
14
+ constructor
15
+ );
16
+ class FunctionalController extends Controller {
17
+ constructor(component, constructor) {
18
+ super(component);
19
+ const originalExports = this.exports;
20
+ try {
21
+ setAmbientComponent(this.component);
22
+ const value = constructor(this.component, this);
23
+ const constructorChangedExports = this.exports !== originalExports;
24
+ if (isPromise(value)) {
25
+ if (!constructorChangedExports) {
26
+ this.setProvisionalExports(value);
27
+ }
28
+ const resolved = value.then((result) => {
29
+ this.exports = result;
30
+ super.catchUpLifecycle();
31
+ }).catch((error) => {
32
+ this.P.reject(error);
33
+ console.error(error);
34
+ });
35
+ this.onLoad(async () => await resolved);
36
+ } else {
37
+ if (!constructorChangedExports || value !== void 0) {
38
+ this.exports = value;
39
+ }
40
+ queueMicrotask(() => super.catchUpLifecycle());
41
+ }
42
+ } catch (error) {
43
+ this.P.reject(error);
44
+ console.error(error);
45
+ }
46
+ }
47
+ /** Noop - will be called in the constructor instead */
48
+ catchUpLifecycle() {
49
+ return;
50
+ }
51
+ }
52
+ const proxy = proxyExports(FunctionalController);
53
+ const useWatchAttributes = (attributes, callback) => new AttributeWatchController(attributes, callback);
54
+ class AttributeWatchController extends Controller {
55
+ #observer;
56
+ #attributes;
57
+ #callback;
58
+ constructor(attributes, callback) {
59
+ super();
60
+ if (isServer) {
61
+ return;
62
+ }
63
+ this.#attributes = attributes;
64
+ this.#callback = callback;
65
+ this.#observer = new MutationObserver((mutations) => {
66
+ mutations.forEach((mutation) => {
67
+ if (attributes.includes(mutation.attributeName)) {
68
+ callback.call(
69
+ this.component,
70
+ this.component.el.getAttribute(mutation.attributeName),
71
+ mutation.oldValue,
72
+ mutation.attributeName
73
+ );
74
+ }
75
+ });
76
+ });
77
+ }
78
+ hostConnected() {
79
+ this.#attributes.forEach((attribute) => {
80
+ if (this.component.el.hasAttribute(attribute)) {
81
+ this.#callback.call(this.component, null, this.component.el.getAttribute(attribute), attribute);
82
+ }
83
+ });
84
+ this.#observer.observe(this.component.el, {
85
+ attributes: true,
86
+ attributeOldValue: true,
87
+ attributeFilter: this.#attributes
88
+ });
89
+ }
90
+ hostDisconnected() {
91
+ this.#observer.disconnect();
92
+ }
93
+ }
94
+ const load = makeController;
95
+ const toFunction = (Class) => (...args) => {
96
+ const ambientControllers = retrieveParentControllers();
97
+ const instance = new Class(...args);
98
+ setParentController(ambientControllers.at(-1));
99
+ return instance;
100
+ };
101
+ const useMedia = (query) => makeController((_component, controller) => {
102
+ const media = globalThis.matchMedia(query);
103
+ const changed = () => {
104
+ controller.exports = media.matches;
105
+ };
106
+ changed();
107
+ controller.onLifecycle(() => {
108
+ media.addEventListener("change", changed);
109
+ return () => media.removeEventListener("change", changed);
110
+ });
111
+ return void 0;
112
+ });
113
+ const defaultDirection = "ltr";
114
+ const useDirection = () => makeController((component, controller) => {
115
+ controller.exports = defaultDirection;
116
+ controller.onLifecycle(() => {
117
+ const callback = () => {
118
+ const dir = getElementAttribute(component.el, "dir", defaultDirection);
119
+ controller.exports = dir === "rtl" ? "rtl" : "ltr";
120
+ };
121
+ callback();
122
+ return observeAncestorsMutation(component.el, ["dir"], callback);
123
+ });
124
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
125
+ trackKey(
126
+ component,
127
+ (resolved) => {
128
+ if (resolved?.key === "dir") {
129
+ throw new Error(
130
+ `Do not assign this controller to a prop called \`dir\` as that will overwrite the \`dir\` attribute on the host element - component should not be setting the \`dir\` attribute on itself. Instead, assign this controller to a property called \`direction\`.`
131
+ );
132
+ }
133
+ },
134
+ controller.exports
135
+ );
136
+ }
137
+ return void 0;
138
+ });
139
+ const makeT9nController = (getAssetPath) => (options = {}) => (
140
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
141
+ makeController((component, controller) => {
142
+ const locale = getElementLocales(component.el);
143
+ const pending = { ["_lang"]: locale.lang, ["_t9nLocale"]: locale.t9nLocale, ["_loading"]: true };
144
+ const componentWithOverrides = component;
145
+ controller.onLifecycle(
146
+ () => startLocaleObserver(
147
+ component.el,
148
+ () => getAssetPath("./assets"),
149
+ ({ t9nLocale, t9nStrings, lang }) => {
150
+ const withoutOverrides = {
151
+ ...t9nStrings,
152
+ ["_lang"]: lang,
153
+ ["_t9nLocale"]: t9nLocale,
154
+ ["_loading"]: false
155
+ };
156
+ controller.exports = withoutOverrides;
157
+ const label = t9nStrings.componentLabel;
158
+ if (typeof label === "string" && "label" in component && component.label == null) {
159
+ component.label ??= label;
160
+ }
161
+ applyOverrides(componentWithOverrides.messageOverrides);
162
+ },
163
+ options.name
164
+ )
165
+ );
166
+ const applyOverrides = (messageOverrides) => {
167
+ const currentValue = controller.exports;
168
+ const rawMessages = currentValue["_original"] ?? currentValue;
169
+ const updated = deepMerge(rawMessages, messageOverrides);
170
+ if (messageOverrides) {
171
+ updated["_original"] = rawMessages;
172
+ }
173
+ controller.exports = updated;
174
+ };
175
+ if ("messageOverrides" in componentWithOverrides) {
176
+ controller.onUpdate((changes) => {
177
+ if (changes.has("messageOverrides")) {
178
+ applyOverrides(componentWithOverrides.messageOverrides);
179
+ }
180
+ });
181
+ }
182
+ if (options.blocking) {
183
+ controller.setProvisionalExports(pending, false);
184
+ return controller.ready;
185
+ } else {
186
+ return pending;
187
+ }
188
+ })
189
+ );
190
+ const deepMerge = (original, overwrites) => {
191
+ if (!overwrites) {
192
+ return original;
193
+ }
194
+ const merged = { ...original };
195
+ Object.entries(overwrites).forEach(([key, value]) => {
196
+ if (typeof value === "object") {
197
+ merged[key] = deepMerge(original[key], value);
198
+ } else {
199
+ merged[key] = value ?? original[key];
200
+ }
201
+ });
202
+ return merged;
203
+ };
204
+ const usePropertyChange = (_component) => propertyChangeController;
205
+ const eventName = "arcgisPropertyChange";
206
+ const propertyChangeController = (...toWatch) => {
207
+ const component = retrieveComponent();
208
+ const eventEmitter = createEventFactory(eventName, void 0, component);
209
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
210
+ toWatch.forEach((prop) => {
211
+ const descriptor = component.constructor.elementProperties.get(prop);
212
+ const isProp = descriptor !== void 0 && descriptor.state !== true;
213
+ if (!isProp) {
214
+ throw new Error(
215
+ `For usePropertyChange to emit event on "${prop}" property change, you should add @property() to ${prop} in ${component.el.localName}`
216
+ );
217
+ }
218
+ });
219
+ }
220
+ let isFirst = true;
221
+ component.manager.onUpdated((changes) => {
222
+ if (isFirst || !component.el.isConnected) {
223
+ isFirst = false;
224
+ return;
225
+ }
226
+ for (const name of toWatch) {
227
+ if (changes.has(name)) {
228
+ eventEmitter.emit({ name });
229
+ }
230
+ }
231
+ });
232
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
233
+ trackKey(
234
+ component,
235
+ (resolution) => {
236
+ if (resolution === void 0 || resolution.isReactive || resolution.key !== eventName) {
237
+ throw new Error(
238
+ `For consistency, usePropertyChange must be assigned to an arcgisPropertyChange property and that property should not have @property() or @state() decorators: arcgisPropertyChange = usePropertyChange<this>()("prop1", "prop2");`
239
+ );
240
+ }
241
+ },
242
+ eventEmitter
243
+ );
244
+ }
245
+ return eventEmitter;
246
+ };
247
+ export {
248
+ Controller,
249
+ G as GenericController,
250
+ h as bypassReadOnly,
251
+ g as bypassSetter,
252
+ c as controllerSymbol,
253
+ n as getControllersCount,
254
+ m as isController,
255
+ k as keyTrackResolve,
256
+ load,
257
+ makeController,
258
+ makeGenericController,
259
+ makeT9nController,
260
+ proxyExports,
261
+ retrieveComponent,
262
+ toFunction,
263
+ trackKey,
264
+ l as trackPropKey,
265
+ j as trackPropertyKey,
266
+ useDirection,
267
+ useMedia,
268
+ usePropertyChange,
269
+ useWatchAttributes
270
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Load a value from a promise and provide it to the component
3
+ *
4
+ * Documentation: https://qawebgis.esri.com/components/lumina/controllers/load
5
+ */
6
+ export declare const load: <T>(loader: () => Promise<T>) => T;
@@ -0,0 +1,27 @@
1
+ import { Controller } from './Controller';
2
+ import { ControllerLifecycleMethods } from './types';
3
+ /**
4
+ * If you wish to directly expose the "exports" property of your controller,
5
+ * rather than the entire controller class, wrap your class definition in
6
+ * "proxyExports".
7
+ *
8
+ * This is especially convenient when your exports is not an object, or it is a
9
+ * dynamically created object, and so you don't want your Controller's methods
10
+ * interfering with the keys on the exported value.
11
+ *
12
+ * "proxyExports" is the default behavior for all controllers declared using
13
+ * the makeController()/makeGenericController() function
14
+ *
15
+ * @remarks
16
+ * If using readonly(), and controller updates its exports, the readonly prop
17
+ * will still get updated
18
+ *
19
+ * @remarks
20
+ * (Advanced) If you wish to use proxyExports() in a class that does not
21
+ * extend Controller class and does not have a useControllerManager(), then your
22
+ * class must subclass a class with the following constructor:
23
+ * `constructor() { setAmbientController(this); }`. This
24
+ * is necessary for proxyExports() to receive a reference to your object
25
+ * implicitly, and before any of your default values are assigned.
26
+ */
27
+ export declare const proxyExports: <Exports, const Parameters extends unknown[]>(Class: new (...args: Parameters) => ControllerLifecycleMethods & Pick<Controller<Exports>, "component" | "exports" | "onUpdate" | "watchExports">) => ((...args: Parameters) => Exports);
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Mocking utility for changing auto-destroy timeout in ControllerManager to 0ms.
3
+ * Also, returns a convenient promise that resolves after the timeout.
4
+ */
5
+ export declare function autoDestroyMock(timeout?: number): () => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare function captureConsoleErrors(): unknown[][];
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A tiny helper for using a class-based controller as if it's a function.
3
+ * Main advantage of this is that it's a bit shorter to type.
4
+ *
5
+ * This utility can be used for converting non-controller classes to functions
6
+ * too
7
+ */
8
+ export declare const toFunction: <T, const P extends unknown[]>(Class: new (...args: P) => T) => ((...args: P) => T);