@arcgis/lumina 4.33.0-next.16 → 4.33.0-next.160

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 (58) 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 +68 -0
  9. package/dist/controllers/accessor/index.d.ts +4 -0
  10. package/dist/controllers/accessor/index.js +245 -0
  11. package/dist/controllers/accessor/reEmitEvent.d.ts +10 -0
  12. package/dist/controllers/accessor/store.d.ts +17 -0
  13. package/dist/controllers/accessor/useAccessor.d.ts +76 -0
  14. package/dist/controllers/functional.d.ts +19 -0
  15. package/dist/controllers/index.d.ts +24 -0
  16. package/dist/controllers/index.js +270 -0
  17. package/dist/controllers/load.d.ts +6 -0
  18. package/dist/controllers/proxyExports.d.ts +27 -0
  19. package/dist/controllers/tests/autoDestroyMock.d.ts +5 -0
  20. package/dist/controllers/tests/utils.d.ts +1 -0
  21. package/dist/controllers/toFunction.d.ts +8 -0
  22. package/dist/controllers/trackKey.d.ts +8 -0
  23. package/dist/controllers/trackPropKey.d.ts +21 -0
  24. package/dist/controllers/trackPropertyKey.d.ts +29 -0
  25. package/dist/controllers/types.d.ts +187 -0
  26. package/dist/controllers/useDirection.d.ts +11 -0
  27. package/dist/controllers/useMedia.d.ts +8 -0
  28. package/dist/controllers/usePropertyChange.d.ts +14 -0
  29. package/dist/controllers/useT9n.d.ts +48 -0
  30. package/dist/controllers/useWatchAttributes.d.ts +7 -0
  31. package/dist/controllers/utils.d.ts +12 -0
  32. package/dist/createEvent.d.ts +8 -3
  33. package/dist/decorators.d.ts +2 -2
  34. package/dist/devOnlyDetectIncorrectLazyUsages.d.ts +1 -1
  35. package/dist/hmrSupport.d.ts +1 -1
  36. package/dist/hmrSupport.js +22 -28
  37. package/dist/index.d.ts +17 -16
  38. package/dist/index.js +423 -194
  39. package/dist/jsx/baseTypes.d.ts +13 -9
  40. package/dist/jsx/directives.d.ts +25 -7
  41. package/dist/jsx/generatedTypes.d.ts +420 -90
  42. package/dist/jsx/types.d.ts +5 -32
  43. package/dist/lazyLoad-DUvrNd2L.js +406 -0
  44. package/dist/lazyLoad.d.ts +27 -72
  45. package/dist/lifecycleSupport.d.ts +2 -2
  46. package/dist/makeRuntime.d.ts +148 -0
  47. package/dist/proxyExports-Cdzj7WL_.js +60 -0
  48. package/dist/render.d.ts +5 -0
  49. package/dist/runtime.d.ts +4 -107
  50. package/dist/stencilSsrCompatibility/index.d.ts +2 -6
  51. package/dist/stencilSsrCompatibility/index.js +2 -3
  52. package/dist/typings/importMeta.d.ts +2 -2
  53. package/dist/utils.d.ts +8 -0
  54. package/dist/wrappersUtils.d.ts +13 -1
  55. package/package.json +7 -6
  56. package/dist/chunk-NO7HOBNA.js +0 -421
  57. package/dist/chunk-PGHUBTOM.js +0 -21
  58. package/dist/wrappersUtils.test.d.ts +0 -1
@@ -0,0 +1,245 @@
1
+ import { isEsriInternalEnv } from "@arcgis/components-utils";
2
+ import { r as retrieveComponent, f as createEventFactory, G as GenericController, l as trackPropKey, t as trackKey } from "../../Controller-BQOv8BAL.js";
3
+ import { on, watch } from "@arcgis/core/core/reactiveUtils.js";
4
+ import { p as proxyExports } from "../../proxyExports-Cdzj7WL_.js";
5
+ import { createObservable, trackAccess } from "@arcgis/core/applications/Components/reactiveUtils.js";
6
+ import { property, subclass } from "@arcgis/core/core/accessorSupport/decorators.js";
7
+ import Accessor from "@arcgis/core/core/Accessor.js";
8
+ const reEmitEvent = (getEventedAccessor, eventName) => {
9
+ const component = retrieveComponent();
10
+ const manager = component.manager;
11
+ manager.onLoaded(() => manager.onLifecycle(() => on(getEventedAccessor, eventName, emitter.emit)));
12
+ const emitter = createEventFactory();
13
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
14
+ if (typeof emitter !== "object" || emitter === null || !("emit" in emitter) || typeof emitter.emit !== "function") {
15
+ throw new Error(`Expected to find $createEvent static property on Lumina's LitElement`);
16
+ }
17
+ }
18
+ return emitter;
19
+ };
20
+ const makeAccessorController = (createInstance, _options) => (component) => proxy(component, createInstance);
21
+ class AccessorController extends GenericController {
22
+ constructor(component, createInstance) {
23
+ super(component);
24
+ this.Y = /* @__PURE__ */ new Map();
25
+ this.A = void 0;
26
+ this.#exportsObservable = createObservable();
27
+ const that = this;
28
+ that.#createInstance = createInstance;
29
+ that.Z();
30
+ that.setProvisionalExports(
31
+ makeBinderProxy(
32
+ component,
33
+ new WeakRef(that),
34
+ component.M.length - 1,
35
+ that.instance,
36
+ that.Y
37
+ ),
38
+ false
39
+ );
40
+ trackPropKey(
41
+ component,
42
+ (resolved) => {
43
+ if (resolved) {
44
+ const handle = watch(
45
+ // If the property to which controller is assigned is public, the user may
46
+ // manually create an accessor instance and assign it to this property
47
+ // We pick it up and replace our created accessor instance with user's.
48
+ () => component[resolved],
49
+ (newInstance) => {
50
+ if (newInstance === that.instance) {
51
+ return;
52
+ }
53
+ const oldInstance = that.instance;
54
+ that.exports = newInstance;
55
+ that.instance = newInstance;
56
+ that.Y.forEach(
57
+ (propName, propertyName) => component.requestUpdate(propName, oldInstance[propertyName])
58
+ );
59
+ if (that.#isInstanceOwner) {
60
+ oldInstance.destroy();
61
+ }
62
+ that.#isInstanceOwner = false;
63
+ },
64
+ { sync: true }
65
+ );
66
+ that.onDestroy(handle.remove);
67
+ }
68
+ },
69
+ that.exports
70
+ );
71
+ }
72
+ #isInstanceOwner;
73
+ #exportsObservable;
74
+ #createInstance;
75
+ get exports() {
76
+ trackAccess(this.#exportsObservable);
77
+ return super.exports;
78
+ }
79
+ set exports(value) {
80
+ super.exports = value;
81
+ this.#exportsObservable.notify();
82
+ }
83
+ /** @private */
84
+ Z() {
85
+ const that = this;
86
+ that.instance = "prototype" in that.#createInstance && "declaredClass" in that.#createInstance.prototype ? new that.#createInstance() : that.#createInstance();
87
+ that.#isInstanceOwner = true;
88
+ }
89
+ hostConnected() {
90
+ this.exports = this.instance;
91
+ }
92
+ // FEATURE: is there a way to detect that accessor does not need to be destroyed?
93
+ // Is it possible to write accessors that don't need to be destroyed?
94
+ hostDestroy() {
95
+ if (this.#isInstanceOwner) {
96
+ this.instance.destroy?.();
97
+ }
98
+ }
99
+ }
100
+ const proxy = proxyExports(AccessorController);
101
+ const makeBinderProxy = (component, accessorControllerRef, accessorControllerIndex, instance, boundProperties) => new Proxy(instance, {
102
+ get: (target, propertyName) => {
103
+ const value = target[propertyName];
104
+ if (
105
+ // Possibly called by the JS engine
106
+ typeof propertyName === "symbol" || // Already bound?
107
+ boundProperties.has(propertyName)
108
+ ) {
109
+ return value;
110
+ }
111
+ const accessorController = component.M[accessorControllerIndex];
112
+ accessorController.A = propertyName;
113
+ return trackKey(
114
+ component,
115
+ (resolved) => {
116
+ accessorController.A = void 0;
117
+ if (resolved !== void 0) {
118
+ const propName = resolved.key;
119
+ boundProperties.set(propertyName, propName);
120
+ const descriptor = component.constructor.getPropertyOptions(
121
+ propName
122
+ );
123
+ if (process.env.NODE_ENV !== "production" && isEsriInternalEnv()) {
124
+ if (!(propertyName in instance)) {
125
+ throw new Error(`"${propertyName}" does not exist on the accessor instance`);
126
+ }
127
+ const accessorController2 = component.M[accessorControllerIndex];
128
+ if (descriptor.i !== void 0 && descriptor.i !== accessorControllerIndex) {
129
+ console.error(component.M[descriptor.i], accessorController2);
130
+ throw Error(
131
+ `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.`
132
+ );
133
+ }
134
+ if (accessorController2 !== accessorControllerRef.deref()) {
135
+ console.error(accessorController2);
136
+ throw Error(
137
+ `Expected controller at index ${accessorControllerIndex} to be instance of useAccessor but it is not.`
138
+ );
139
+ }
140
+ const isFlippingBoolean = resolved.key.toLowerCase().includes("disable");
141
+ const collidesWithNativeProp = propertyName in HTMLElement.prototype;
142
+ const collidesWithCustomProp = accessorControllerRef.deref().constructor.devOnly$allowedPropNameMismatches?.has(propName) === true;
143
+ if (resolved.key !== propertyName && !collidesWithNativeProp && !collidesWithCustomProp && !isFlippingBoolean) {
144
+ throw new Error(
145
+ `Tried to bind "${resolved?.key}" property to "${propertyName.toString()}" - property names must match`
146
+ );
147
+ }
148
+ if (!resolved.isReactive) {
149
+ throw new Error(
150
+ `For two-way binding with Accessor to work, the property on your component must have @property() or @state() decorator. "${propertyName.toString()}" has neither`
151
+ );
152
+ }
153
+ }
154
+ const shouldFlipBoolean = propertyName !== propName && propName.toLowerCase().includes("disable");
155
+ watchBoundProperty(accessorControllerRef, descriptor, propertyName, propName, shouldFlipBoolean);
156
+ if (descriptor.i === void 0) {
157
+ bindPropToProperty(descriptor, accessorControllerIndex, propertyName, shouldFlipBoolean);
158
+ }
159
+ }
160
+ },
161
+ value
162
+ );
163
+ }
164
+ });
165
+ const watchBoundProperty = (controllerRef, descriptor, propertyName, propName, shouldFlipBoolean, _handle) => _handle = watch(
166
+ () => {
167
+ const controller = controllerRef.deref();
168
+ return controller === void 0 || controller.component.manager.destroyed ? _handle = _handle.remove() : controller.exports[propertyName];
169
+ },
170
+ (_, oldValue) => {
171
+ if (!_handle) {
172
+ return;
173
+ }
174
+ const component = controllerRef.deref().component;
175
+ component?.requestUpdate(propName, shouldFlipBoolean ? !oldValue : oldValue);
176
+ descriptor.c = false;
177
+ },
178
+ // At present, since useAccessor initializes the Accessor instance without
179
+ // any properties, it assumes that there is no need to do initial sync of
180
+ // accessor properties to the component, especially since the component
181
+ // setter always gets the newest value from the Accessor instance anyway.
182
+ // We might wish to change that if view model is shared between multiple
183
+ // components and has default value for some property. Even then, this issue
184
+ // will only manifest itself in default value not being reflected to
185
+ // attribute (). If fixing above becomes important, can do so by adding
186
+ // `initial: true` here and updating the above code to only call .notify()
187
+ // if hasChanged returns true (see reference implementation in
188
+ // _handleInstanceChanged). Not doing so yet as it is an edge case that is
189
+ // easy to work around and proper fix will add overhead to the startup of
190
+ // each component.
191
+ { sync: true }
192
+ );
193
+ const bindPropToProperty = (descriptor, accessorControllerIndex, propertyName, shouldFlipBoolean) => {
194
+ descriptor.d.get = function() {
195
+ const value = this.M[accessorControllerIndex]?.exports[propertyName];
196
+ return shouldFlipBoolean ? !value : value;
197
+ };
198
+ descriptor.d.set = function(newValue) {
199
+ const accessorController = this.M[accessorControllerIndex];
200
+ if (accessorController.A !== propertyName) {
201
+ accessorController.exports[propertyName] = shouldFlipBoolean ? !newValue : newValue;
202
+ }
203
+ };
204
+ };
205
+ const getAccessorControllerBoundProperties = (controller) => controller.Y;
206
+ const reCreateAccessor = (instance, component) => {
207
+ const accessorController = component.manager.useRefSync(instance);
208
+ accessorController?.hostDestroy();
209
+ accessorController?.Z();
210
+ accessorController?.hostConnected();
211
+ if (process.env.NODE_ENV !== "production" && accessorController === void 0) {
212
+ console.error("Unable to resolve the useAccessor controller from the provided value");
213
+ }
214
+ };
215
+ const createStore = (defaultValues) => {
216
+ const SubClass = class extends Accessor {
217
+ };
218
+ Object.entries(defaultValues).forEach(([name, value]) => property({ value })(SubClass.prototype, name));
219
+ const State = subclass()(SubClass);
220
+ return new State();
221
+ };
222
+ const createLegacyStore = (defaultState) => {
223
+ const defaultValues = typeof defaultState === "function" ? defaultState() : defaultState;
224
+ const state = createStore(defaultValues);
225
+ return {
226
+ state,
227
+ get: (propName) => state[propName],
228
+ set: (propName, value) => state.set(propName, value),
229
+ onChange: (propName, callback) => watch(
230
+ () => state[propName],
231
+ (newValue) => callback(newValue),
232
+ { sync: true }
233
+ ).remove
234
+ };
235
+ };
236
+ export {
237
+ AccessorController,
238
+ createLegacyStore,
239
+ createStore,
240
+ getAccessorControllerBoundProperties,
241
+ makeAccessorController,
242
+ makeBinderProxy,
243
+ reCreateAccessor,
244
+ reEmitEvent
245
+ };
@@ -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,17 @@
1
+ import { default as Accessor } from '@arcgis/core/core/Accessor.js';
2
+ /**
3
+ * See https://qawebgis.esri.com/components/lumina/controllers/useAccessor#createstore-utility
4
+ */
5
+ export declare const createStore: <T extends Record<string, unknown>>(defaultValues: T | (() => T)) => __esri.Accessor & T;
6
+ /** @deprecated Use {@link createStore} instead */
7
+ export declare const createLegacyStore: <T extends Record<string, unknown>>(defaultState: T | (() => T)) => ObservableMap<T>;
8
+ /** @deprecated Use {@link createStore} instead */
9
+ export type ObservableMap<T> = {
10
+ state: Accessor & T;
11
+ /** @deprecated Use state[propertyName] instead */
12
+ get: <P extends keyof T>(propName: P & string) => T[P];
13
+ /** @deprecated Use state[propertyName]=value instead */
14
+ set: <P extends keyof T>(propName: P & string, value: T[P]) => void;
15
+ /** @deprecated Use reactiveUtils.watch instead */
16
+ onChange: <Key extends keyof T>(propName: Key, callback: (newValue: T[Key]) => void) => () => void;
17
+ };
@@ -0,0 +1,76 @@
1
+ import { 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
+ /** @private */
50
+ _currentlyBindingPropertyName?: string;
51
+ /**
52
+ * (development only) Allow these props to mismatch the name of the Accessor's
53
+ * property to avoid collisions
54
+ *
55
+ * @private
56
+ */
57
+ static devOnly$allowedPropNameMismatches?: ReadonlySet<string>;
58
+ get exports(): Accessor;
59
+ set exports(value: Accessor);
60
+ constructor(component: ExtraRequires & Requires<Props, Accessor>, createInstance: ((props?: Props) => Accessor) | (new (props?: Props) => Accessor));
61
+ /** @private */
62
+ _createAccessorInstance(): void;
63
+ hostConnected(): void;
64
+ hostDestroy(): void;
65
+ }
66
+ type MinimalAccessorController = Pick<AccessorController<never, __esri.Accessor>, "_currentlyBindingPropertyName" | "exports"> & {
67
+ component: LitElement;
68
+ };
69
+ export declare const makeBinderProxy: (component: LitElement, accessorControllerRef: WeakRef<MinimalAccessorController & {
70
+ constructor: MinimalAccessorController["constructor"] & {
71
+ devOnly$allowedPropNameMismatches?: ReadonlySet<string>;
72
+ };
73
+ }>, accessorControllerIndex: number, instance: __esri.Accessor, boundProperties: Map<string, string>) => unknown;
74
+ export declare const getAccessorControllerBoundProperties: <Accessor extends __esri.Accessor>(controller: AccessorController<unknown, Accessor>) => Map<string & keyof Accessor, string>;
75
+ export declare const reCreateAccessor: (instance: __esri.Accessor, component: LitElement) => void;
76
+ 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;