@api-client/ui 0.1.7 → 0.1.9

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.
@@ -1,25 +1,51 @@
1
1
  import { navigateScreen } from './ApplicationRoute.js';
2
- export var ActivityState;
3
- (function (ActivityState) {
4
- ActivityState[ActivityState["Initialized"] = 0] = "Initialized";
5
- ActivityState[ActivityState["Created"] = 1] = "Created";
6
- ActivityState[ActivityState["Started"] = 2] = "Started";
7
- ActivityState[ActivityState["Resumed"] = 3] = "Resumed";
8
- ActivityState[ActivityState["Paused"] = 4] = "Paused";
9
- ActivityState[ActivityState["Stopped"] = 5] = "Stopped";
10
- ActivityState[ActivityState["Destroyed"] = 6] = "Destroyed";
11
- })(ActivityState || (ActivityState = {}));
2
+ export var ActivityLifecycle;
3
+ (function (ActivityLifecycle) {
4
+ /**
5
+ * The activity is initialized, but not yet created.
6
+ * This is the initial state of the activity.
7
+ */
8
+ ActivityLifecycle[ActivityLifecycle["Initialized"] = 0] = "Initialized";
9
+ /**
10
+ * The activity is created, but not yet started.
11
+ * This is the state after the `onCreate()` method is called.
12
+ */
13
+ ActivityLifecycle[ActivityLifecycle["Created"] = 1] = "Created";
14
+ /**
15
+ * The activity is started, but not yet resumed.
16
+ * This is the state after the `onStart()` method is called.
17
+ */
18
+ ActivityLifecycle[ActivityLifecycle["Started"] = 2] = "Started";
19
+ /**
20
+ * The activity is resumed and visible to the user.
21
+ * This is the state after the `onResume()` method is called.
22
+ */
23
+ ActivityLifecycle[ActivityLifecycle["Resumed"] = 3] = "Resumed";
24
+ /**
25
+ * The activity is paused, but still visible to the user.
26
+ * This is the state after the `onPause()` method is called.
27
+ */
28
+ ActivityLifecycle[ActivityLifecycle["Paused"] = 4] = "Paused";
29
+ /**
30
+ * The activity is stopped and no longer visible to the user.
31
+ * This is the state after the `onStop()` method is called.
32
+ */
33
+ ActivityLifecycle[ActivityLifecycle["Stopped"] = 5] = "Stopped";
34
+ /**
35
+ * The activity is destroyed and no longer exists.
36
+ * This is the state after the `onDestroy()` method is called.
37
+ */
38
+ ActivityLifecycle[ActivityLifecycle["Destroyed"] = 6] = "Destroyed";
39
+ })(ActivityLifecycle || (ActivityLifecycle = {}));
12
40
  export var IntentFlags;
13
41
  (function (IntentFlags) {
14
42
  /**
15
43
  * Marks that the activity should be rendered as a modal.
16
44
  */
17
- // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
18
45
  IntentFlags[IntentFlags["Modal"] = 1] = "Modal";
19
46
  /**
20
47
  * The activity is started for result.
21
48
  */
22
- // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
23
49
  IntentFlags[IntentFlags["ForResult"] = 2] = "ForResult";
24
50
  /**
25
51
  * When set, the intent data is passed by reference.
@@ -27,7 +53,6 @@ export var IntentFlags;
27
53
  * This is useful when the data is large and you want to avoid copying it
28
54
  * or when you want to share the same data between activities.
29
55
  */
30
- // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
31
56
  IntentFlags[IntentFlags["ByReference"] = 4] = "ByReference";
32
57
  })(IntentFlags || (IntentFlags = {}));
33
58
  export var IntentResult;
@@ -129,14 +154,13 @@ export class ActivityManager {
129
154
  await info.activity.onNewIntent(intent);
130
155
  // TODO: Check if the activity is destroyed.
131
156
  this.setupRoute(intent);
132
- // this.currentActivity = info.activity
133
157
  await this.updateCurrentActivity(info.activity, false);
134
158
  return;
135
159
  }
136
160
  const activity = this.buildActivity(intent);
137
161
  if (currentActivity) {
138
162
  await currentActivity.onPause();
139
- currentActivity.state = ActivityState.Paused;
163
+ currentActivity.lifecycle = ActivityLifecycle.Paused;
140
164
  }
141
165
  const activityId = this.generateActivityId();
142
166
  const stackEntry = { activity, id: activityId, intent, action: intent.action };
@@ -155,7 +179,7 @@ export class ActivityManager {
155
179
  // the activity finished and the manager already took care of this situation.
156
180
  return;
157
181
  }
158
- activity.state = ActivityState.Created;
182
+ activity.lifecycle = ActivityLifecycle.Created;
159
183
  await this.updateCurrentActivity(activity, !!isModal);
160
184
  if (this.isDestroyed(activity)) {
161
185
  // the activity finished and the manager already took care of this situation.
@@ -203,7 +227,7 @@ export class ActivityManager {
203
227
  await this.startActivity(deepCopy);
204
228
  }
205
229
  isDestroyed(activity) {
206
- return activity.state === ActivityState.Destroyed;
230
+ return activity.lifecycle === ActivityLifecycle.Destroyed;
207
231
  }
208
232
  /**
209
233
  * @param activity The activity to finish.
@@ -216,22 +240,22 @@ export class ActivityManager {
216
240
  if (index !== -1) {
217
241
  const stackEntry = stack.splice(index, 1)[0];
218
242
  await stackEntry.activity.onPause();
219
- stackEntry.activity.state = ActivityState.Paused;
243
+ stackEntry.activity.lifecycle = ActivityLifecycle.Paused;
220
244
  await stackEntry.activity.onStop();
221
- stackEntry.activity.state = ActivityState.Stopped;
245
+ stackEntry.activity.lifecycle = ActivityLifecycle.Stopped;
222
246
  await stackEntry.activity.onDestroy();
223
- stackEntry.activity.state = ActivityState.Destroyed;
247
+ stackEntry.activity.lifecycle = ActivityLifecycle.Destroyed;
224
248
  await this.manageActivityResult(stackEntry.activity, stackEntry.intent);
225
249
  // Resume the previous activity
226
250
  await this.bringLastActivityToFront();
227
251
  }
228
252
  else {
229
- if (activity.state === ActivityState.Created) {
253
+ if (activity.lifecycle === ActivityLifecycle.Created) {
230
254
  await activity.onStop();
231
- activity.state = ActivityState.Stopped;
255
+ activity.lifecycle = ActivityLifecycle.Stopped;
232
256
  }
233
257
  await activity.onDestroy();
234
- activity.state = ActivityState.Destroyed;
258
+ activity.lifecycle = ActivityLifecycle.Destroyed;
235
259
  // This can happen when an activity finishes in one of the callback methods,
236
260
  // before it is added to the stack. In that case, we bring the last activity back to the front.
237
261
  await this.bringLastActivityToFront();
@@ -244,12 +268,12 @@ export class ActivityManager {
244
268
  const all = [...this.activityStack, ...this.modalActivityStack];
245
269
  const target = all.find((entry) => entry.activity.hasRequestCode(requestCode));
246
270
  if (target) {
247
- if (target.activity.state === ActivityState.Destroyed) {
271
+ if (target.activity.lifecycle === ActivityLifecycle.Destroyed) {
248
272
  return;
249
273
  }
250
- if (target.activity.state === ActivityState.Resumed) {
274
+ if (target.activity.lifecycle === ActivityLifecycle.Resumed) {
251
275
  await target.activity.onPause();
252
- target.activity.state = ActivityState.Paused;
276
+ target.activity.lifecycle = ActivityLifecycle.Paused;
253
277
  }
254
278
  const intentCopy = structuredClone(intent);
255
279
  intentCopy.data = activity.getResult();
@@ -271,11 +295,11 @@ export class ActivityManager {
271
295
  }
272
296
  }
273
297
  getTopActivity() {
274
- const topModal = this.modalActivityStack.findLast((a) => a.activity.state === ActivityState.Resumed);
298
+ const topModal = this.modalActivityStack.findLast((a) => a.activity.lifecycle === ActivityLifecycle.Resumed);
275
299
  if (topModal) {
276
300
  return topModal.activity;
277
301
  }
278
- const top = this.activityStack.findLast((a) => a.activity.state === ActivityState.Resumed);
302
+ const top = this.activityStack.findLast((a) => a.activity.lifecycle === ActivityLifecycle.Resumed);
279
303
  return top ? top.activity : undefined;
280
304
  }
281
305
  getCurrentActivity() {
@@ -323,52 +347,52 @@ export class ActivityManager {
323
347
  this.setupStyles(activity, this.currentActivity);
324
348
  if (this.currentActivity &&
325
349
  this.currentActivity !== activity &&
326
- this.currentActivity.state !== ActivityState.Destroyed &&
350
+ this.currentActivity.lifecycle !== ActivityLifecycle.Destroyed &&
327
351
  // Make sure we don't pause the current activity if it's already paused.
328
- this.currentActivity.state !== ActivityState.Paused) {
352
+ this.currentActivity.lifecycle !== ActivityLifecycle.Paused) {
329
353
  await this.currentActivity.onPause();
330
- this.currentActivity.state = ActivityState.Paused;
354
+ this.currentActivity.lifecycle = ActivityLifecycle.Paused;
331
355
  }
332
- if (activity.state === ActivityState.Paused) {
356
+ if (activity.lifecycle === ActivityLifecycle.Paused) {
333
357
  await activity.onResume();
334
358
  if (this.isDestroyed(activity)) {
335
359
  return;
336
360
  }
337
- activity.state = ActivityState.Resumed;
361
+ activity.lifecycle = ActivityLifecycle.Resumed;
338
362
  activity.requestUpdate();
339
363
  }
340
- else if (activity.state === ActivityState.Stopped) {
364
+ else if (activity.lifecycle === ActivityLifecycle.Stopped) {
341
365
  await activity.onRestart();
342
- activity.state = ActivityState.Resumed;
366
+ activity.lifecycle = ActivityLifecycle.Resumed;
343
367
  }
344
- else if (activity.state === ActivityState.Destroyed) {
368
+ else if (activity.lifecycle === ActivityLifecycle.Destroyed) {
345
369
  throw new Error(`Invalid state. The activity is already destroyed.`);
346
370
  }
347
- else if (activity.state === ActivityState.Created) {
371
+ else if (activity.lifecycle === ActivityLifecycle.Created) {
348
372
  await activity.onStart();
349
373
  if (this.isDestroyed(activity)) {
350
374
  return;
351
375
  }
352
- activity.state = ActivityState.Started;
376
+ activity.lifecycle = ActivityLifecycle.Started;
353
377
  await activity.onResume();
354
378
  if (this.isDestroyed(activity)) {
355
379
  return;
356
380
  }
357
- activity.state = ActivityState.Resumed;
381
+ activity.lifecycle = ActivityLifecycle.Resumed;
358
382
  activity.requestUpdate();
359
383
  }
360
- else if (activity.state === ActivityState.Started) {
384
+ else if (activity.lifecycle === ActivityLifecycle.Started) {
361
385
  await activity.onResume();
362
386
  if (this.isDestroyed(activity)) {
363
387
  return;
364
388
  }
365
- activity.state = ActivityState.Resumed;
389
+ activity.lifecycle = ActivityLifecycle.Resumed;
366
390
  activity.requestUpdate();
367
391
  }
368
- else if (activity.state === ActivityState.Initialized) {
392
+ else if (activity.lifecycle === ActivityLifecycle.Initialized) {
369
393
  // TODO: Figure out intent passing here.
370
394
  await activity.onCreate();
371
- activity.state = ActivityState.Created;
395
+ activity.lifecycle = ActivityLifecycle.Created;
372
396
  if (this.isDestroyed(activity)) {
373
397
  // the activity finished and the manager already took care of this situation.
374
398
  return;
@@ -377,12 +401,12 @@ export class ActivityManager {
377
401
  if (this.isDestroyed(activity)) {
378
402
  return;
379
403
  }
380
- activity.state = ActivityState.Started;
404
+ activity.lifecycle = ActivityLifecycle.Started;
381
405
  await activity.onResume();
382
406
  if (this.isDestroyed(activity)) {
383
407
  return;
384
408
  }
385
- activity.state = ActivityState.Resumed;
409
+ activity.lifecycle = ActivityLifecycle.Resumed;
386
410
  activity.requestUpdate();
387
411
  }
388
412
  if (!isModal) {
@@ -1 +1 @@
1
- {"version":3,"file":"ActivityManager.js","sourceRoot":"","sources":["../../../src/core/ActivityManager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Activity } from './Activity.js'\nimport type { Application } from './Application.js'\nimport { navigateScreen } from './ApplicationRoute.js'\n\nexport enum ActivityState {\n Initialized,\n Created,\n Started,\n Resumed,\n Paused,\n Stopped,\n Destroyed,\n}\n\nexport enum IntentFlags {\n /**\n * Marks that the activity should be rendered as a modal.\n */\n // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member\n Modal = 1 << 0,\n /**\n * The activity is started for result.\n */\n // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member\n ForResult = 1 << 1,\n /**\n * When set, the intent data is passed by reference.\n * By default the activity manager makes a copy of the intent data.\n * This is useful when the data is large and you want to avoid copying it\n * or when you want to share the same data between activities.\n */\n // eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member\n ByReference = 1 << 2,\n}\n\nexport interface Intent {\n action: string\n data?: unknown\n category?: string[]\n flags?: number\n /**\n * The request code used to distinguish between different activities.\n */\n requestCode?: number\n}\n\nexport enum IntentResult {\n RESULT_CANCELED,\n RESULT_OK,\n}\n\n/**\n * Defines the information stored for each activity on the stack:\n * the Activity instance, a unique id, and optionally the Intent that started the activity\n * (useful for restoring state).\n */\ninterface ActivityStackEntry {\n /**\n * The instance of the activity.\n */\n activity: Activity\n /**\n * Activity's unique ID.\n */\n id: string\n /**\n * The intent that started the activity.\n */\n intent: Intent\n /**\n * The action name the activity is registered for.\n */\n action: string\n}\n\n/**\n * Manages application activities.\n *\n * An activity is a screen or a portion of a rendered screen that has its own\n * lifecycle methods and routing.\n *\n * An activity is registered by its class definition. Because of that, activities\n * cannot have constructors that require own parameters. Activities have to be\n * self contained or use the event system to request data.\n */\nexport class ActivityManager {\n private currentActivity?: Activity\n\n /**\n * Stores activity *classes* by unique ID (action name).\n */\n private activityClasses = new Map<string, typeof Activity>()\n\n /**\n * Represents the activity stack. It is used to manage\n * the UI state after calling the back action.\n */\n private activityStack: ActivityStackEntry[] = []\n\n /**\n * A stack of activities that are rendered over other activities\n * in a dialog.\n */\n private modalActivityStack: ActivityStackEntry[] = []\n\n private generateActivityId(): string {\n return Math.random().toString(36).substring(2, 15)\n }\n\n #parent: Application\n\n constructor(parent: Application) {\n this.#parent = parent\n // this.reflectEvent = this.reflectEvent.bind(this)\n }\n\n registerActivity(action: string, activityClass: typeof Activity): void {\n if (this.activityClasses.has(action)) {\n // eslint-disable-next-line no-console\n console.warn(`Activity with action \"${action}\" already registered.`, new Error().stack)\n }\n this.activityClasses.set(action, activityClass)\n }\n\n // protected reflectEvent<T extends Event>(event: T): T {\n // const copy = Reflect.construct(event.constructor, [event.type, event])\n // const dispatched = this.#parent.events.dispatchEvent(copy)\n // if (!dispatched) {\n // event.preventDefault()\n // }\n // return copy\n // }\n\n /**\n * Creates an activity and pushes it into the stack, but it does not initialize any of the lifecycle methods.\n * It is a way to put an activity at some place of the stack,\n * but it will be only initialized when other activities finis.\n *\n * Note, if you add an uninitialized activity and you won't add more activities then this activity may never run.\n * Make sure that there's always another activity.\n *\n * @param intent The intent that created this activity.\n */\n async createActivity(intent: Intent): Promise<void> {\n const activity = this.buildActivity(intent)\n const activityId = this.generateActivityId()\n const stackEntry: ActivityStackEntry = { activity, id: activityId, intent, action: intent.action }\n this.activityStack.push(stackEntry)\n }\n\n setupRoute(intent: Intent): void {\n if (intent.data) {\n const typed = intent.data as { uri?: string }\n if (typed.uri) {\n navigateScreen(typed.uri)\n }\n }\n }\n\n /**\n * Starts a new activity and brings it to the foreground.\n *\n * @param intent The intent that created this activity.\n */\n async startActivity(intent: Intent): Promise<void> {\n const { currentActivity, activityStack } = this\n const lastIndex = activityStack.findLastIndex((entry) => entry.action === intent.action)\n // if the activity is in the history list, we bring it up and update intent.\n if (lastIndex > -1) {\n const info = activityStack[lastIndex]\n activityStack.splice(lastIndex, 1)\n activityStack.push({\n id: info.id,\n activity: info.activity,\n action: info.action,\n intent,\n })\n await info.activity.onNewIntent(intent)\n // TODO: Check if the activity is destroyed.\n this.setupRoute(intent)\n // this.currentActivity = info.activity\n await this.updateCurrentActivity(info.activity, false)\n return\n }\n const activity = this.buildActivity(intent)\n if (currentActivity) {\n await currentActivity.onPause()\n currentActivity.state = ActivityState.Paused\n }\n\n const activityId = this.generateActivityId()\n const stackEntry: ActivityStackEntry = { activity, id: activityId, intent, action: intent.action }\n // Modal activities are pretty much the same as regular activities but are rendered on top\n // of other activities. We keep track of them on another stack as all modal activities must\n // finish before returning to the regular stack.\n const isModal = (intent.flags ?? 0) & IntentFlags.Modal\n if (isModal) {\n this.modalActivityStack.push(stackEntry)\n } else {\n this.activityStack.push(stackEntry)\n }\n await activity.onCreate(intent)\n if (this.isDestroyed(activity)) {\n // the activity finished and the manager already took care of this situation.\n return\n }\n activity.state = ActivityState.Created\n\n await this.updateCurrentActivity(activity, !!isModal)\n if (this.isDestroyed(activity)) {\n // the activity finished and the manager already took care of this situation.\n return\n }\n this.setupRoute(intent)\n }\n\n private buildActivity(intent: Intent): Activity {\n const action = intent.action\n if (!this.activityClasses.has(action)) {\n throw new Error(`No activity class registered for action: ${action}`)\n }\n\n const ActivityClass = this.activityClasses.get(action)\n if (!ActivityClass) {\n throw new Error(`No activity class registered for action: ${action}`)\n }\n\n // We use the container to resolve dependencies, if any.\n // const activity = (await container.make(ActivityClass, [this.#parent])) as Activity\n return new ActivityClass(this.#parent)\n }\n\n /**\n * Starts an activity that should return a result to the calling activity.\n * The result should be a unique number across the application.\n * @param intent The intent to start the activity.\n * @param requestCode The request code used to match the activity result.\n */\n async startActivityForResult(intent: Intent, requestCode: number): Promise<void> {\n intent.requestCode = requestCode\n const byReference = (intent.flags ?? 0) & IntentFlags.ByReference\n const shallowCopy = { ...intent }\n const data = shallowCopy.data\n if (byReference) {\n delete shallowCopy.data\n }\n const deepCopy = structuredClone(shallowCopy)\n if (data && byReference) {\n deepCopy.data = data\n }\n if (deepCopy.flags) {\n deepCopy.flags = deepCopy.flags | IntentFlags.ForResult\n } else {\n deepCopy.flags = IntentFlags.ForResult\n }\n await this.startActivity(deepCopy)\n }\n\n isDestroyed(activity: Activity): boolean {\n return activity.state === ActivityState.Destroyed\n }\n\n /**\n * @param activity The activity to finish.\n */\n async finishActivity(activity: Activity): Promise<void> {\n this.setupStyles(undefined, activity)\n const isModal = this.modalActivityStack.some((entry) => entry.activity === activity)\n const stack = isModal ? this.modalActivityStack : this.activityStack\n const index = stack.findIndex((entry) => entry.activity === activity)\n if (index !== -1) {\n const stackEntry = stack.splice(index, 1)[0]\n\n await stackEntry.activity.onPause()\n stackEntry.activity.state = ActivityState.Paused\n await stackEntry.activity.onStop()\n stackEntry.activity.state = ActivityState.Stopped\n await stackEntry.activity.onDestroy()\n stackEntry.activity.state = ActivityState.Destroyed\n\n await this.manageActivityResult(stackEntry.activity, stackEntry.intent)\n\n // Resume the previous activity\n await this.bringLastActivityToFront()\n } else {\n if (activity.state === ActivityState.Created) {\n await activity.onStop()\n activity.state = ActivityState.Stopped\n }\n await activity.onDestroy()\n activity.state = ActivityState.Destroyed\n // This can happen when an activity finishes in one of the callback methods,\n // before it is added to the stack. In that case, we bring the last activity back to the front.\n await this.bringLastActivityToFront()\n }\n this.#parent.requestUpdate()\n }\n\n private async manageActivityResult(activity: Activity, intent: Intent): Promise<void> {\n const { flags = 0, requestCode = -1 } = intent\n if (flags & IntentFlags.ForResult) {\n const all = [...this.activityStack, ...this.modalActivityStack]\n const target = all.find((entry) => entry.activity.hasRequestCode(requestCode))\n if (target) {\n if (target.activity.state === ActivityState.Destroyed) {\n return\n }\n if (target.activity.state === ActivityState.Resumed) {\n await target.activity.onPause()\n target.activity.state = ActivityState.Paused\n }\n const intentCopy = structuredClone(intent)\n intentCopy.data = activity.getResult()\n await target.activity.onActivityResult(requestCode, activity.resultCode, intentCopy)\n }\n }\n }\n\n private async bringLastActivityToFront(): Promise<void> {\n if (this.modalActivityStack.length > 0) {\n const previousEntry = this.modalActivityStack[this.activityStack.length - 1]\n await this.updateCurrentActivity(previousEntry.activity, false)\n } else if (this.activityStack.length > 0) {\n const previousEntry = this.activityStack[this.activityStack.length - 1]\n await this.updateCurrentActivity(previousEntry.activity, false)\n } else {\n this.currentActivity = undefined // No more activities\n }\n }\n\n getTopActivity(): Activity | undefined {\n const topModal = this.modalActivityStack.findLast((a) => a.activity.state === ActivityState.Resumed)\n if (topModal) {\n return topModal.activity\n }\n const top = this.activityStack.findLast((a) => a.activity.state === ActivityState.Resumed)\n return top ? top.activity : undefined\n }\n\n getCurrentActivity(): Activity | undefined {\n return this.currentActivity\n }\n\n /**\n * Sets the styles for the current activity.\n * This method adds or removes CSS classes based on the activity's class name\n * and action, allowing for dynamic styling based on the active activity.\n * @param activity The activity to set styles for.\n * If not provided, it will not set any styles.\n * If the activity is the same as the current one, it does nothing.\n */\n setupStyles(activity?: Activity, oldActivity?: Activity): void {\n if (activity === oldActivity) {\n return\n }\n const root = document?.documentElement\n if (!root) {\n return\n }\n if (oldActivity) {\n const ctor = oldActivity.constructor as typeof Activity\n root.classList.remove(ctor.name.toLowerCase())\n if (ctor.action) {\n root.classList.remove(ctor.action.replace(/\\//g, '-'))\n }\n }\n if (activity) {\n const ctor = activity.constructor as typeof Activity\n root.classList.add(ctor.name.toLowerCase())\n if (ctor.action) {\n root.classList.add(ctor.action.replace(/\\//g, '-'))\n }\n }\n }\n\n /**\n * A helper method to handle the transition between activities, ensuring\n * lifecycle methods are called in the correct order (pause the previous activity,\n * then start/resume the new one). This centralizes lifecycle management.\n *\n * @param activity The activity to bring to the foreground.\n */\n private async updateCurrentActivity(activity: Activity, isModal: boolean): Promise<void> {\n this.setupStyles(activity, this.currentActivity)\n if (\n this.currentActivity &&\n this.currentActivity !== activity &&\n this.currentActivity.state !== ActivityState.Destroyed &&\n // Make sure we don't pause the current activity if it's already paused.\n this.currentActivity.state !== ActivityState.Paused\n ) {\n await this.currentActivity.onPause()\n this.currentActivity.state = ActivityState.Paused\n }\n if (activity.state === ActivityState.Paused) {\n await activity.onResume()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.state = ActivityState.Resumed\n activity.requestUpdate()\n } else if (activity.state === ActivityState.Stopped) {\n await activity.onRestart()\n activity.state = ActivityState.Resumed\n } else if (activity.state === ActivityState.Destroyed) {\n throw new Error(`Invalid state. The activity is already destroyed.`)\n } else if (activity.state === ActivityState.Created) {\n await activity.onStart()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.state = ActivityState.Started\n await activity.onResume()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.state = ActivityState.Resumed\n activity.requestUpdate()\n } else if (activity.state === ActivityState.Started) {\n await activity.onResume()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.state = ActivityState.Resumed\n activity.requestUpdate()\n } else if (activity.state === ActivityState.Initialized) {\n // TODO: Figure out intent passing here.\n await activity.onCreate()\n activity.state = ActivityState.Created\n if (this.isDestroyed(activity)) {\n // the activity finished and the manager already took care of this situation.\n return\n }\n await activity.onStart()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.state = ActivityState.Started\n await activity.onResume()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.state = ActivityState.Resumed\n activity.requestUpdate()\n }\n if (!isModal) {\n // With a modal activity, it renders directly to the `<body>` and renders outside\n // of the normal rendering flow. We keep the previous activity rendered.\n this.currentActivity = activity\n }\n }\n\n /**\n * Allows navigating back through the activity stack.\n * Call `ActivityManager.navigateBack()` when the user performs a back action\n * (e.g., clicks a back button).\n */\n async navigateBack(): Promise<void> {\n if (this.activityStack.length > 1 && this.currentActivity) {\n // Finish current, which will resume previous\n await this.finishActivity(this.currentActivity)\n }\n // Else do nothing (or display a message, or exit the app)\n }\n\n createRequestCode(): number {\n const min = 1000\n const max = 9999\n return Math.floor(Math.random() * (max - min) + min)\n }\n\n findActiveActivity(action: string): Activity | undefined {\n return this.activityStack.find((entry) => entry.action === action)?.activity\n }\n}\n"]}
1
+ {"version":3,"file":"ActivityManager.js","sourceRoot":"","sources":["../../../src/core/ActivityManager.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Activity } from './Activity.js'\nimport type { Application } from './Application.js'\nimport { navigateScreen } from './ApplicationRoute.js'\n\nexport enum ActivityLifecycle {\n /**\n * The activity is initialized, but not yet created.\n * This is the initial state of the activity.\n */\n Initialized,\n /**\n * The activity is created, but not yet started.\n * This is the state after the `onCreate()` method is called.\n */\n Created,\n /**\n * The activity is started, but not yet resumed.\n * This is the state after the `onStart()` method is called.\n */\n Started,\n /**\n * The activity is resumed and visible to the user.\n * This is the state after the `onResume()` method is called.\n */\n Resumed,\n /**\n * The activity is paused, but still visible to the user.\n * This is the state after the `onPause()` method is called.\n */\n Paused,\n /**\n * The activity is stopped and no longer visible to the user.\n * This is the state after the `onStop()` method is called.\n */\n Stopped,\n /**\n * The activity is destroyed and no longer exists.\n * This is the state after the `onDestroy()` method is called.\n */\n Destroyed,\n}\n\nexport enum IntentFlags {\n /**\n * Marks that the activity should be rendered as a modal.\n */\n Modal = 1 << 0,\n /**\n * The activity is started for result.\n */\n ForResult = 1 << 1,\n /**\n * When set, the intent data is passed by reference.\n * By default the activity manager makes a copy of the intent data.\n * This is useful when the data is large and you want to avoid copying it\n * or when you want to share the same data between activities.\n */\n ByReference = 1 << 2,\n}\n\nexport interface Intent {\n action: string\n data?: unknown\n category?: string[]\n flags?: number\n /**\n * The request code used to distinguish between different activities.\n */\n requestCode?: number\n}\n\nexport enum IntentResult {\n RESULT_CANCELED,\n RESULT_OK,\n}\n\n/**\n * Defines the information stored for each activity on the stack:\n * the Activity instance, a unique id, and optionally the Intent that started the activity\n * (useful for restoring state).\n */\ninterface ActivityStackEntry {\n /**\n * The instance of the activity.\n */\n activity: Activity\n /**\n * Activity's unique ID.\n */\n id: string\n /**\n * The intent that started the activity.\n */\n intent: Intent\n /**\n * The action name the activity is registered for.\n */\n action: string\n}\n\n/**\n * Manages application activities.\n *\n * An activity is a screen or a portion of a rendered screen that has its own\n * lifecycle methods and routing.\n *\n * An activity is registered by its class definition. Because of that, activities\n * cannot have constructors that require own parameters. Activities have to be\n * self contained or use the event system to request data.\n */\nexport class ActivityManager {\n private currentActivity?: Activity\n\n /**\n * Stores activity *classes* by unique ID (action name).\n */\n private activityClasses = new Map<string, typeof Activity>()\n\n /**\n * Represents the activity stack. It is used to manage\n * the UI state after calling the back action.\n */\n private activityStack: ActivityStackEntry[] = []\n\n /**\n * A stack of activities that are rendered over other activities\n * in a dialog.\n */\n private modalActivityStack: ActivityStackEntry[] = []\n\n private generateActivityId(): string {\n return Math.random().toString(36).substring(2, 15)\n }\n\n #parent: Application\n\n constructor(parent: Application) {\n this.#parent = parent\n // this.reflectEvent = this.reflectEvent.bind(this)\n }\n\n registerActivity(action: string, activityClass: typeof Activity): void {\n if (this.activityClasses.has(action)) {\n // eslint-disable-next-line no-console\n console.warn(`Activity with action \"${action}\" already registered.`, new Error().stack)\n }\n this.activityClasses.set(action, activityClass)\n }\n\n // protected reflectEvent<T extends Event>(event: T): T {\n // const copy = Reflect.construct(event.constructor, [event.type, event])\n // const dispatched = this.#parent.events.dispatchEvent(copy)\n // if (!dispatched) {\n // event.preventDefault()\n // }\n // return copy\n // }\n\n /**\n * Creates an activity and pushes it into the stack, but it does not initialize any of the lifecycle methods.\n * It is a way to put an activity at some place of the stack,\n * but it will be only initialized when other activities finis.\n *\n * Note, if you add an uninitialized activity and you won't add more activities then this activity may never run.\n * Make sure that there's always another activity.\n *\n * @param intent The intent that created this activity.\n */\n async createActivity(intent: Intent): Promise<void> {\n const activity = this.buildActivity(intent)\n const activityId = this.generateActivityId()\n const stackEntry: ActivityStackEntry = { activity, id: activityId, intent, action: intent.action }\n this.activityStack.push(stackEntry)\n }\n\n setupRoute(intent: Intent): void {\n if (intent.data) {\n const typed = intent.data as { uri?: string }\n if (typed.uri) {\n navigateScreen(typed.uri)\n }\n }\n }\n\n /**\n * Starts a new activity and brings it to the foreground.\n *\n * @param intent The intent that created this activity.\n */\n async startActivity(intent: Intent): Promise<void> {\n const { currentActivity, activityStack } = this\n const lastIndex = activityStack.findLastIndex((entry) => entry.action === intent.action)\n // if the activity is in the history list, we bring it up and update intent.\n if (lastIndex > -1) {\n const info = activityStack[lastIndex]\n activityStack.splice(lastIndex, 1)\n activityStack.push({\n id: info.id,\n activity: info.activity,\n action: info.action,\n intent,\n })\n await info.activity.onNewIntent(intent)\n // TODO: Check if the activity is destroyed.\n this.setupRoute(intent)\n await this.updateCurrentActivity(info.activity, false)\n return\n }\n const activity = this.buildActivity(intent)\n if (currentActivity) {\n await currentActivity.onPause()\n currentActivity.lifecycle = ActivityLifecycle.Paused\n }\n\n const activityId = this.generateActivityId()\n const stackEntry: ActivityStackEntry = { activity, id: activityId, intent, action: intent.action }\n // Modal activities are pretty much the same as regular activities but are rendered on top\n // of other activities. We keep track of them on another stack as all modal activities must\n // finish before returning to the regular stack.\n const isModal = (intent.flags ?? 0) & IntentFlags.Modal\n if (isModal) {\n this.modalActivityStack.push(stackEntry)\n } else {\n this.activityStack.push(stackEntry)\n }\n await activity.onCreate(intent)\n if (this.isDestroyed(activity)) {\n // the activity finished and the manager already took care of this situation.\n return\n }\n activity.lifecycle = ActivityLifecycle.Created\n\n await this.updateCurrentActivity(activity, !!isModal)\n if (this.isDestroyed(activity)) {\n // the activity finished and the manager already took care of this situation.\n return\n }\n this.setupRoute(intent)\n }\n\n private buildActivity(intent: Intent): Activity {\n const action = intent.action\n if (!this.activityClasses.has(action)) {\n throw new Error(`No activity class registered for action: ${action}`)\n }\n\n const ActivityClass = this.activityClasses.get(action)\n if (!ActivityClass) {\n throw new Error(`No activity class registered for action: ${action}`)\n }\n\n // We use the container to resolve dependencies, if any.\n // const activity = (await container.make(ActivityClass, [this.#parent])) as Activity\n return new ActivityClass(this.#parent)\n }\n\n /**\n * Starts an activity that should return a result to the calling activity.\n * The result should be a unique number across the application.\n * @param intent The intent to start the activity.\n * @param requestCode The request code used to match the activity result.\n */\n async startActivityForResult(intent: Intent, requestCode: number): Promise<void> {\n intent.requestCode = requestCode\n const byReference = (intent.flags ?? 0) & IntentFlags.ByReference\n const shallowCopy = { ...intent }\n const data = shallowCopy.data\n if (byReference) {\n delete shallowCopy.data\n }\n const deepCopy = structuredClone(shallowCopy)\n if (data && byReference) {\n deepCopy.data = data\n }\n if (deepCopy.flags) {\n deepCopy.flags = deepCopy.flags | IntentFlags.ForResult\n } else {\n deepCopy.flags = IntentFlags.ForResult\n }\n await this.startActivity(deepCopy)\n }\n\n isDestroyed(activity: Activity): boolean {\n return activity.lifecycle === ActivityLifecycle.Destroyed\n }\n\n /**\n * @param activity The activity to finish.\n */\n async finishActivity(activity: Activity): Promise<void> {\n this.setupStyles(undefined, activity)\n const isModal = this.modalActivityStack.some((entry) => entry.activity === activity)\n const stack = isModal ? this.modalActivityStack : this.activityStack\n const index = stack.findIndex((entry) => entry.activity === activity)\n if (index !== -1) {\n const stackEntry = stack.splice(index, 1)[0]\n\n await stackEntry.activity.onPause()\n stackEntry.activity.lifecycle = ActivityLifecycle.Paused\n await stackEntry.activity.onStop()\n stackEntry.activity.lifecycle = ActivityLifecycle.Stopped\n await stackEntry.activity.onDestroy()\n stackEntry.activity.lifecycle = ActivityLifecycle.Destroyed\n\n await this.manageActivityResult(stackEntry.activity, stackEntry.intent)\n\n // Resume the previous activity\n await this.bringLastActivityToFront()\n } else {\n if (activity.lifecycle === ActivityLifecycle.Created) {\n await activity.onStop()\n activity.lifecycle = ActivityLifecycle.Stopped\n }\n await activity.onDestroy()\n activity.lifecycle = ActivityLifecycle.Destroyed\n // This can happen when an activity finishes in one of the callback methods,\n // before it is added to the stack. In that case, we bring the last activity back to the front.\n await this.bringLastActivityToFront()\n }\n this.#parent.requestUpdate()\n }\n\n private async manageActivityResult(activity: Activity, intent: Intent): Promise<void> {\n const { flags = 0, requestCode = -1 } = intent\n if (flags & IntentFlags.ForResult) {\n const all = [...this.activityStack, ...this.modalActivityStack]\n const target = all.find((entry) => entry.activity.hasRequestCode(requestCode))\n if (target) {\n if (target.activity.lifecycle === ActivityLifecycle.Destroyed) {\n return\n }\n if (target.activity.lifecycle === ActivityLifecycle.Resumed) {\n await target.activity.onPause()\n target.activity.lifecycle = ActivityLifecycle.Paused\n }\n const intentCopy = structuredClone(intent)\n intentCopy.data = activity.getResult()\n await target.activity.onActivityResult(requestCode, activity.resultCode, intentCopy)\n }\n }\n }\n\n private async bringLastActivityToFront(): Promise<void> {\n if (this.modalActivityStack.length > 0) {\n const previousEntry = this.modalActivityStack[this.activityStack.length - 1]\n await this.updateCurrentActivity(previousEntry.activity, false)\n } else if (this.activityStack.length > 0) {\n const previousEntry = this.activityStack[this.activityStack.length - 1]\n await this.updateCurrentActivity(previousEntry.activity, false)\n } else {\n this.currentActivity = undefined // No more activities\n }\n }\n\n getTopActivity(): Activity | undefined {\n const topModal = this.modalActivityStack.findLast((a) => a.activity.lifecycle === ActivityLifecycle.Resumed)\n if (topModal) {\n return topModal.activity\n }\n const top = this.activityStack.findLast((a) => a.activity.lifecycle === ActivityLifecycle.Resumed)\n return top ? top.activity : undefined\n }\n\n getCurrentActivity(): Activity | undefined {\n return this.currentActivity\n }\n\n /**\n * Sets the styles for the current activity.\n * This method adds or removes CSS classes based on the activity's class name\n * and action, allowing for dynamic styling based on the active activity.\n * @param activity The activity to set styles for.\n * If not provided, it will not set any styles.\n * If the activity is the same as the current one, it does nothing.\n */\n setupStyles(activity?: Activity, oldActivity?: Activity): void {\n if (activity === oldActivity) {\n return\n }\n const root = document?.documentElement\n if (!root) {\n return\n }\n if (oldActivity) {\n const ctor = oldActivity.constructor as typeof Activity\n root.classList.remove(ctor.name.toLowerCase())\n if (ctor.action) {\n root.classList.remove(ctor.action.replace(/\\//g, '-'))\n }\n }\n if (activity) {\n const ctor = activity.constructor as typeof Activity\n root.classList.add(ctor.name.toLowerCase())\n if (ctor.action) {\n root.classList.add(ctor.action.replace(/\\//g, '-'))\n }\n }\n }\n\n /**\n * A helper method to handle the transition between activities, ensuring\n * lifecycle methods are called in the correct order (pause the previous activity,\n * then start/resume the new one). This centralizes lifecycle management.\n *\n * @param activity The activity to bring to the foreground.\n */\n private async updateCurrentActivity(activity: Activity, isModal: boolean): Promise<void> {\n this.setupStyles(activity, this.currentActivity)\n if (\n this.currentActivity &&\n this.currentActivity !== activity &&\n this.currentActivity.lifecycle !== ActivityLifecycle.Destroyed &&\n // Make sure we don't pause the current activity if it's already paused.\n this.currentActivity.lifecycle !== ActivityLifecycle.Paused\n ) {\n await this.currentActivity.onPause()\n this.currentActivity.lifecycle = ActivityLifecycle.Paused\n }\n if (activity.lifecycle === ActivityLifecycle.Paused) {\n await activity.onResume()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.lifecycle = ActivityLifecycle.Resumed\n activity.requestUpdate()\n } else if (activity.lifecycle === ActivityLifecycle.Stopped) {\n await activity.onRestart()\n activity.lifecycle = ActivityLifecycle.Resumed\n } else if (activity.lifecycle === ActivityLifecycle.Destroyed) {\n throw new Error(`Invalid state. The activity is already destroyed.`)\n } else if (activity.lifecycle === ActivityLifecycle.Created) {\n await activity.onStart()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.lifecycle = ActivityLifecycle.Started\n await activity.onResume()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.lifecycle = ActivityLifecycle.Resumed\n activity.requestUpdate()\n } else if (activity.lifecycle === ActivityLifecycle.Started) {\n await activity.onResume()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.lifecycle = ActivityLifecycle.Resumed\n activity.requestUpdate()\n } else if (activity.lifecycle === ActivityLifecycle.Initialized) {\n // TODO: Figure out intent passing here.\n await activity.onCreate()\n activity.lifecycle = ActivityLifecycle.Created\n if (this.isDestroyed(activity)) {\n // the activity finished and the manager already took care of this situation.\n return\n }\n await activity.onStart()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.lifecycle = ActivityLifecycle.Started\n await activity.onResume()\n if (this.isDestroyed(activity)) {\n return\n }\n activity.lifecycle = ActivityLifecycle.Resumed\n activity.requestUpdate()\n }\n if (!isModal) {\n // With a modal activity, it renders directly to the `<body>` and renders outside\n // of the normal rendering flow. We keep the previous activity rendered.\n this.currentActivity = activity\n }\n }\n\n /**\n * Allows navigating back through the activity stack.\n * Call `ActivityManager.navigateBack()` when the user performs a back action\n * (e.g., clicks a back button).\n */\n async navigateBack(): Promise<void> {\n if (this.activityStack.length > 1 && this.currentActivity) {\n // Finish current, which will resume previous\n await this.finishActivity(this.currentActivity)\n }\n // Else do nothing (or display a message, or exit the app)\n }\n\n createRequestCode(): number {\n const min = 1000\n const max = 9999\n return Math.floor(Math.random() * (max - min) + min)\n }\n\n findActiveActivity(action: string): Activity | undefined {\n return this.activityStack.find((entry) => entry.action === action)?.activity\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/core/Application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAClD,OAAO,EAAE,eAAe,EAAiB,MAAM,sBAAsB,CAAA;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAA;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AACD;;;;;;;;;;;;;;;;;GAiBG;AACH,8BAAsB,WAAY,SAAQ,WAAW;;IACnD,OAAO,CAAC,sBAAsB,CAAuC;IAMrE;;OAEG;IACH,IAAI,KAAK,IAAI,YAAY,CAExB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,eAAe,CAE7B;IAID;;;;OAIG;IACH,IAAI,MAAM,IAAI,WAAW,CAExB;IAID,IAAI,QAAQ,IAAI,mBAAmB,CAElC;IAED;;OAEG;IACH,IAAI,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAE9C;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED;;OAEG;gBACS,UAAU,EAAE,WAAW,GAAG,MAAM;IAY5C;;OAEG;IACI,aAAa,CAAC,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAI5D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAExC;;;OAGG;IACH,MAAM,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9B;;;OAGG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;;;;;;OAOG;IACH,MAAM,IAAI,cAAc,GAAG,OAAO,OAAO;IASzC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;;OAGG;IACH,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,IAAI;IAO7C;;OAEG;IACU,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAKjC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOlC,kBAAkB,IAAI,QAAQ,GAAG,SAAS;IAI1C;;;OAGG;IACH,cAAc;IAId,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;CAGrD"}
1
+ {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/core/Application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAClD,OAAO,EAAE,eAAe,EAAqB,MAAM,sBAAsB,CAAA;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAA;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AACD;;;;;;;;;;;;;;;;;GAiBG;AACH,8BAAsB,WAAY,SAAQ,WAAW;;IACnD,OAAO,CAAC,sBAAsB,CAAuC;IAMrE;;OAEG;IACH,IAAI,KAAK,IAAI,YAAY,CAExB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,eAAe,CAE7B;IAID;;;;OAIG;IACH,IAAI,MAAM,IAAI,WAAW,CAExB;IAID,IAAI,QAAQ,IAAI,mBAAmB,CAElC;IAED;;OAEG;IACH,IAAI,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAE9C;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED;;OAEG;gBACS,UAAU,EAAE,WAAW,GAAG,MAAM;IAY5C;;OAEG;IACI,aAAa,CAAC,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;IAI5D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAExC;;;OAGG;IACH,MAAM,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9B;;;OAGG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;;;;;;OAOG;IACH,MAAM,IAAI,cAAc,GAAG,OAAO,OAAO;IASzC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;;OAGG;IACH,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,IAAI;IAO7C;;OAEG;IACU,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAKjC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOlC,kBAAkB,IAAI,QAAQ,GAAG,SAAS;IAI1C;;;OAGG;IACH,cAAc;IAId,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;CAGrD"}
@@ -1,5 +1,5 @@
1
1
  import { nothing } from 'lit';
2
- import { ActivityManager, ActivityState } from './ActivityManager.js';
2
+ import { ActivityManager, ActivityLifecycle } from './ActivityManager.js';
3
3
  import { ApplicationRenderer } from './renderer/ApplicationRenderer.js';
4
4
  import { ThemeManager } from './ThemeManager.js';
5
5
  /**
@@ -111,7 +111,7 @@ export class Application extends EventTarget {
111
111
  render() {
112
112
  const currentActivity = this.#activities.getCurrentActivity();
113
113
  // Only render if started or beyond
114
- if (currentActivity && currentActivity.state >= ActivityState.Started) {
114
+ if (currentActivity && currentActivity.lifecycle >= ActivityLifecycle.Started) {
115
115
  return currentActivity.render();
116
116
  }
117
117
  return nothing;
@@ -1 +1 @@
1
- {"version":3,"file":"Application.js","sourceRoot":"","sources":["../../../src/core/Application.ts"],"names":[],"mappings":"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","sourcesContent":["import { nothing, type TemplateResult } from 'lit'\nimport { ActivityManager, ActivityState } from './ActivityManager.js'\nimport type { Activity } from './Activity.js'\nimport { ApplicationRenderer } from './renderer/ApplicationRenderer.js'\nimport { ThemeManager } from './ThemeManager.js'\n\n/**\n * Allows to fine-tune the update request.\n * For example, if a `Fragment` wants to update only itself, then\n * list other types should be set to false.\n */\nexport interface UpdateRequest {\n /**\n * Whether the whole application should be updated.\n * Default to true.\n */\n app?: boolean\n /**\n * Whether the activity should be updated.\n * Default to true.\n */\n activity?: boolean\n /**\n * Whether the fragment should be updated.\n * Default to true.\n */\n fragment?: boolean\n}\n/**\n * The application represents an application screen that hosts\n * Activities. Activities are managed by the Activity manager.\n *\n * An application is a separate app within the ecosystem. For example,\n * the file browser is one application. The domain designer is another.\n *\n * Each application manages it's own lifecycle. The application is rendered\n * by the lit's library `render()` function. Activities can call application's\n * main `requestUpdate()` function to render the entire application.\n *\n * Activities have the render function that renders its UI.\n * The Activity's UI can be composed of fragments, but this is optional.\n * When an activity uses fragments, they receive control over rendering their\n * UIs. An activity implementation has to take care of passing HTMLElement\n * references to their Fragments to make that happen. Otherwise, the activity\n * has to communicate with their fragments to request to re-render the application.\n */\nexport abstract class Application extends EventTarget {\n private activityUpdateListener = this.handleActivityUpdate.bind(this)\n\n #activities: ActivityManager\n\n #theme: ThemeManager\n\n /**\n * Application's theme manager.\n */\n get theme(): ThemeManager {\n return this.#theme\n }\n\n /**\n * Returns the application's activity manager.\n */\n get manager(): ActivityManager {\n return this.#activities\n }\n\n #events: EventTarget\n\n /**\n * The application main event bus.\n * All activities and fragments use it to communicate.\n * This way, events do not leak outside the application.\n */\n get events(): EventTarget {\n return this.#events\n }\n\n #renderer: ApplicationRenderer\n\n get renderer(): ApplicationRenderer {\n return this.#renderer\n }\n\n /**\n * @type A promise resolved when the render finished.\n */\n get updateComplete(): Promise<void> | undefined {\n return this.#renderer.updateComplete\n }\n\n /**\n * @type True when the application was first rendered.\n */\n get firstRendered(): boolean {\n return this.#renderer.firstRendered\n }\n\n /**\n * @param renderRoot The element or a CSS query to the element where the application will be rendered.\n */\n constructor(renderRoot: HTMLElement | string) {\n super()\n this.#events = new EventTarget()\n this.#activities = new ActivityManager(this)\n this.#renderer = new ApplicationRenderer(this)\n this.#renderer.setRenderRoot(renderRoot)\n this.#theme = new ThemeManager()\n\n // Listen for activity updates\n this.#events.addEventListener('activity:update', this.activityUpdateListener as EventListener)\n }\n\n /**\n * @see {@link ./Renderer.js}\n */\n public setRenderRoot(renderRoot: HTMLElement | string): void {\n this.#renderer.setRenderRoot(renderRoot)\n }\n\n /**\n * Called when the application starts.\n * This is where you should start the initial Activity using\n * `ActivityManager.startActivity(...)`.\n */\n abstract onStart(): void | Promise<void>\n\n /**\n * Called when the application is stopped/closed.\n * Perform cleanup here.\n */\n onStop(): void | Promise<void> {\n //\n }\n\n /**\n * Called when the application was rendered for the first time.\n * Call `super.onFirstRender()` when overriding this method.\n */\n onFirstRender(): void {\n this.#events.dispatchEvent(new Event('app:first-render'))\n }\n\n /**\n * Called when the application was rendered.\n */\n onRendered(): void {\n //\n }\n\n /**\n * The main render method for the Application. Called whenever an activity\n * requests an update. Renders the currently active Activity's content.\n *\n * If you override this method then any activity won't be rendered.\n *\n * @returns The Lit template to render.\n */\n render(): TemplateResult | typeof nothing {\n const currentActivity = this.#activities.getCurrentActivity()\n // Only render if started or beyond\n if (currentActivity && currentActivity.state >= ActivityState.Started) {\n return currentActivity.render()\n }\n return nothing\n }\n\n /**\n * Handles activity update requests and re-renders the application.\n */\n private handleActivityUpdate(e: CustomEvent<UpdateRequest | undefined>): void {\n this.requestUpdate(e.detail || undefined)\n }\n\n /**\n * Requests an update of the application UI. This will call the `render()` method\n * and update the DOM.\n */\n requestUpdate(opts: UpdateRequest = {}): void {\n const { app = true } = opts\n if (app) {\n this.#renderer.requestUpdate()\n }\n }\n\n /**\n * Starts the application by calling onStart and performing an initial render.\n */\n public async run(): Promise<void> {\n await this.onStart()\n this.requestUpdate()\n }\n\n /**\n * Stops the application, performing cleanup if necessary.\n */\n public async stop(): Promise<void> {\n this.#events.removeEventListener('activity:update', this.activityUpdateListener as EventListener)\n // Allow subclasses to clean up\n await this.onStop()\n // ... any other application-level cleanup\n }\n\n getCurrentActivity(): Activity | undefined {\n return this.#activities.getCurrentActivity()\n }\n\n /**\n * Unifies Fragment and Application interfaces.\n * @returns `this`\n */\n getApplication() {\n return this\n }\n\n findActiveActivity(id: string): Activity | undefined {\n return this.#activities.findActiveActivity(id)\n }\n}\n"]}
1
+ {"version":3,"file":"Application.js","sourceRoot":"","sources":["../../../src/core/Application.ts"],"names":[],"mappings":"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","sourcesContent":["import { nothing, type TemplateResult } from 'lit'\nimport { ActivityManager, ActivityLifecycle } from './ActivityManager.js'\nimport type { Activity } from './Activity.js'\nimport { ApplicationRenderer } from './renderer/ApplicationRenderer.js'\nimport { ThemeManager } from './ThemeManager.js'\n\n/**\n * Allows to fine-tune the update request.\n * For example, if a `Fragment` wants to update only itself, then\n * list other types should be set to false.\n */\nexport interface UpdateRequest {\n /**\n * Whether the whole application should be updated.\n * Default to true.\n */\n app?: boolean\n /**\n * Whether the activity should be updated.\n * Default to true.\n */\n activity?: boolean\n /**\n * Whether the fragment should be updated.\n * Default to true.\n */\n fragment?: boolean\n}\n/**\n * The application represents an application screen that hosts\n * Activities. Activities are managed by the Activity manager.\n *\n * An application is a separate app within the ecosystem. For example,\n * the file browser is one application. The domain designer is another.\n *\n * Each application manages it's own lifecycle. The application is rendered\n * by the lit's library `render()` function. Activities can call application's\n * main `requestUpdate()` function to render the entire application.\n *\n * Activities have the render function that renders its UI.\n * The Activity's UI can be composed of fragments, but this is optional.\n * When an activity uses fragments, they receive control over rendering their\n * UIs. An activity implementation has to take care of passing HTMLElement\n * references to their Fragments to make that happen. Otherwise, the activity\n * has to communicate with their fragments to request to re-render the application.\n */\nexport abstract class Application extends EventTarget {\n private activityUpdateListener = this.handleActivityUpdate.bind(this)\n\n #activities: ActivityManager\n\n #theme: ThemeManager\n\n /**\n * Application's theme manager.\n */\n get theme(): ThemeManager {\n return this.#theme\n }\n\n /**\n * Returns the application's activity manager.\n */\n get manager(): ActivityManager {\n return this.#activities\n }\n\n #events: EventTarget\n\n /**\n * The application main event bus.\n * All activities and fragments use it to communicate.\n * This way, events do not leak outside the application.\n */\n get events(): EventTarget {\n return this.#events\n }\n\n #renderer: ApplicationRenderer\n\n get renderer(): ApplicationRenderer {\n return this.#renderer\n }\n\n /**\n * @type A promise resolved when the render finished.\n */\n get updateComplete(): Promise<void> | undefined {\n return this.#renderer.updateComplete\n }\n\n /**\n * @type True when the application was first rendered.\n */\n get firstRendered(): boolean {\n return this.#renderer.firstRendered\n }\n\n /**\n * @param renderRoot The element or a CSS query to the element where the application will be rendered.\n */\n constructor(renderRoot: HTMLElement | string) {\n super()\n this.#events = new EventTarget()\n this.#activities = new ActivityManager(this)\n this.#renderer = new ApplicationRenderer(this)\n this.#renderer.setRenderRoot(renderRoot)\n this.#theme = new ThemeManager()\n\n // Listen for activity updates\n this.#events.addEventListener('activity:update', this.activityUpdateListener as EventListener)\n }\n\n /**\n * @see {@link ./Renderer.js}\n */\n public setRenderRoot(renderRoot: HTMLElement | string): void {\n this.#renderer.setRenderRoot(renderRoot)\n }\n\n /**\n * Called when the application starts.\n * This is where you should start the initial Activity using\n * `ActivityManager.startActivity(...)`.\n */\n abstract onStart(): void | Promise<void>\n\n /**\n * Called when the application is stopped/closed.\n * Perform cleanup here.\n */\n onStop(): void | Promise<void> {\n //\n }\n\n /**\n * Called when the application was rendered for the first time.\n * Call `super.onFirstRender()` when overriding this method.\n */\n onFirstRender(): void {\n this.#events.dispatchEvent(new Event('app:first-render'))\n }\n\n /**\n * Called when the application was rendered.\n */\n onRendered(): void {\n //\n }\n\n /**\n * The main render method for the Application. Called whenever an activity\n * requests an update. Renders the currently active Activity's content.\n *\n * If you override this method then any activity won't be rendered.\n *\n * @returns The Lit template to render.\n */\n render(): TemplateResult | typeof nothing {\n const currentActivity = this.#activities.getCurrentActivity()\n // Only render if started or beyond\n if (currentActivity && currentActivity.lifecycle >= ActivityLifecycle.Started) {\n return currentActivity.render()\n }\n return nothing\n }\n\n /**\n * Handles activity update requests and re-renders the application.\n */\n private handleActivityUpdate(e: CustomEvent<UpdateRequest | undefined>): void {\n this.requestUpdate(e.detail || undefined)\n }\n\n /**\n * Requests an update of the application UI. This will call the `render()` method\n * and update the DOM.\n */\n requestUpdate(opts: UpdateRequest = {}): void {\n const { app = true } = opts\n if (app) {\n this.#renderer.requestUpdate()\n }\n }\n\n /**\n * Starts the application by calling onStart and performing an initial render.\n */\n public async run(): Promise<void> {\n await this.onStart()\n this.requestUpdate()\n }\n\n /**\n * Stops the application, performing cleanup if necessary.\n */\n public async stop(): Promise<void> {\n this.#events.removeEventListener('activity:update', this.activityUpdateListener as EventListener)\n // Allow subclasses to clean up\n await this.onStop()\n // ... any other application-level cleanup\n }\n\n getCurrentActivity(): Activity | undefined {\n return this.#activities.getCurrentActivity()\n }\n\n /**\n * Unifies Fragment and Application interfaces.\n * @returns `this`\n */\n getApplication() {\n return this\n }\n\n findActiveActivity(id: string): Activity | undefined {\n return this.#activities.findActiveActivity(id)\n }\n}\n"]}
@@ -49,7 +49,7 @@ let ModalActivity = (() => {
49
49
  formId = __runInitializers(this, _opened_extraInitializers);
50
50
  onResume() {
51
51
  this.renderRoot = document.createElement('div');
52
- this.renderRoot.classList.add('modal-activit-container');
52
+ this.renderRoot.classList.add('modal-activity-container');
53
53
  document.body.appendChild(this.renderRoot);
54
54
  super.onResume();
55
55
  this.requestUpdate();
@@ -1 +1 @@
1
- {"version":3,"file":"ModalActivity.js","sourceRoot":"","sources":["../../../src/core/ModalActivity.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, type TemplateResult } from 'lit'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { Activity } from './Activity.js'\nimport type { UiDialogClosingReason } from '../md/dialog/internals/Dialog.js'\nimport state from '../decorators/state.js'\nimport { IntentResult } from './ActivityManager.js'\n\nimport '../md/dialog/ui-dialog.js'\nimport '../md/button/ui-text-button.js'\n\nexport interface ActionButtonInit {\n /**\n * The label to use for the button.\n */\n label?: string\n /**\n * Whether the button is disabled.\n */\n disabled?: boolean\n}\n\n/**\n * A special kind of activity that renders content in a modal dialog.\n * When a modal activity is running the underlying activities are paused.\n *\n * A modal activity uses the UiDialogElement to render its content. The dialog\n * is inserted directly into the `<body>` element of the document and rendered\n * in the top layer. Because of that, the modal activity does not support\n * regular rendering logic. It creates its own render root that is used to render\n * the template.\n */\nexport abstract class ModalActivity extends Activity {\n /**\n * The list of classes to apply to the dialog.\n */\n protected dialogClasses: Record<string, boolean> = {}\n /**\n * Controls dialog visibility without controlling the activity state.\n */\n @state() accessor opened = true\n\n /**\n * The id of the form used to render the dialog.\n */\n protected formId?: string\n\n override onResume(): void | Promise<void> {\n this.renderRoot = document.createElement('div')\n this.renderRoot.classList.add('modal-activit-container')\n document.body.appendChild(this.renderRoot)\n super.onResume()\n this.requestUpdate()\n }\n\n override async finish(): Promise<void> {\n if (this.renderRoot) {\n document.body.removeChild(this.renderRoot)\n this.renderRoot = undefined\n }\n await super.finish()\n }\n\n protected handleDialogClosed(e: CustomEvent<UiDialogClosingReason>): void {\n const { cancelled, value } = e.detail\n if (cancelled) {\n this.handleNegativeAction(value)\n } else {\n this.handlePositiveAction(value)\n }\n }\n\n /**\n * Called when the dialog is closed with a negative action.\n * Override this function to handle the negative action.\n * @param value The value passed to the dialog when it is closed.\n */\n protected handleNegativeAction(value: unknown): void {\n this.setResult(IntentResult.RESULT_CANCELED, value)\n this.finish()\n }\n\n /**\n * Called when the dialog is closed with a positive action.\n * Override this function to handle the positive action.\n * @param value The value passed to the dialog when it is closed.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected handlePositiveAction(value: unknown): void {\n this.finish()\n }\n\n /**\n * Override this method to handle the form submission.\n * @param e The submit event.\n */\n protected handleSubmit(e: SubmitEvent): void {\n e.preventDefault()\n }\n\n /**\n * The function called by the rendered when rendering this dialog.\n * This way, the `render()` function is still used as the primary template provider.\n */\n renderDialog(): TemplateResult {\n const classes = {\n activityDialog: true,\n [this.constructor.name.toLowerCase()]: true,\n ...this.dialogClasses,\n }\n return html`<ui-dialog modal .open=\"${this.opened}\" class=\"${classMap(classes)}\" @close=\"${this.handleDialogClosed}\"\n >${this.render()}</ui-dialog\n >`\n }\n\n /**\n * Used with dialogs that render forms. Override the `handleSubmit` method\n * to handle the form submission.\n * @param content The content to render in the form.\n * @param name Optional form name\n */\n protected renderForm(content: TemplateResult, name?: string): TemplateResult {\n if (!this.formId) {\n this.formId = `form-${this.constructor.name.toLowerCase()}`\n }\n return html`<form\n id=\"${this.formId}\"\n name=\"${ifDefined(name)}\"\n class=\"dialog-content\"\n @submit=\"${this.handleSubmit}\"\n >\n ${content}\n </form>`\n }\n\n /**\n * Renders the cancel button for the dialog.\n * @param label The label to use for the cancel button.\n */\n protected renderNegativeButton(init: ActionButtonInit = {}): TemplateResult {\n const { label = 'Cancel' } = init\n return html`<ui-text-button slot=\"button\" type=\"button\" value=\"dismiss\">${label}</ui-text-button>`\n }\n\n /**\n * Renders the submit button for the dialog.\n * If the formId is set, the button will be a submit button.\n * Otherwise, it will be a regular button.\n * @param label The label to use for the submit button.\n */\n protected renderPositiveButton(init: ActionButtonInit = {}): TemplateResult {\n const { label = 'OK', disabled = false } = init\n const { formId } = this\n const type = formId ? 'submit' : 'button'\n // UI buttons have a proper support for form association.\n return html`<ui-text-button\n slot=\"button\"\n ?disabled=\"${disabled}\"\n type=\"${type}\"\n value=\"confirm\"\n form=\"${ifDefined(formId)}\"\n >${label}</ui-text-button\n >`\n }\n\n /**\n * Renders the title for the dialog.\n * @param title The title to render in the dialog.\n */\n protected renderTitle(title: string): TemplateResult {\n return html`<span slot=\"title\">${title}</span>`\n }\n}\n"]}
1
+ {"version":3,"file":"ModalActivity.js","sourceRoot":"","sources":["../../../src/core/ModalActivity.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, type TemplateResult } from 'lit'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { Activity } from './Activity.js'\nimport type { UiDialogClosingReason } from '../md/dialog/internals/Dialog.js'\nimport state from '../decorators/state.js'\nimport { IntentResult } from './ActivityManager.js'\n\nimport '../md/dialog/ui-dialog.js'\nimport '../md/button/ui-text-button.js'\n\nexport interface ActionButtonInit {\n /**\n * The label to use for the button.\n */\n label?: string\n /**\n * Whether the button is disabled.\n */\n disabled?: boolean\n}\n\n/**\n * A special kind of activity that renders content in a modal dialog.\n * When a modal activity is running the underlying activities are paused.\n *\n * A modal activity uses the UiDialogElement to render its content. The dialog\n * is inserted directly into the `<body>` element of the document and rendered\n * in the top layer. Because of that, the modal activity does not support\n * regular rendering logic. It creates its own render root that is used to render\n * the template.\n */\nexport abstract class ModalActivity extends Activity {\n /**\n * The list of classes to apply to the dialog.\n */\n protected dialogClasses: Record<string, boolean> = {}\n /**\n * Controls dialog visibility without controlling the activity state.\n */\n @state() accessor opened = true\n\n /**\n * The id of the form used to render the dialog.\n */\n protected formId?: string\n\n override onResume(): void | Promise<void> {\n this.renderRoot = document.createElement('div')\n this.renderRoot.classList.add('modal-activity-container')\n document.body.appendChild(this.renderRoot)\n super.onResume()\n this.requestUpdate()\n }\n\n override async finish(): Promise<void> {\n if (this.renderRoot) {\n document.body.removeChild(this.renderRoot)\n this.renderRoot = undefined\n }\n await super.finish()\n }\n\n protected handleDialogClosed(e: CustomEvent<UiDialogClosingReason>): void {\n const { cancelled, value } = e.detail\n if (cancelled) {\n this.handleNegativeAction(value)\n } else {\n this.handlePositiveAction(value)\n }\n }\n\n /**\n * Called when the dialog is closed with a negative action.\n * Override this function to handle the negative action.\n * @param value The value passed to the dialog when it is closed.\n */\n protected handleNegativeAction(value: unknown): void {\n this.setResult(IntentResult.RESULT_CANCELED, value)\n this.finish()\n }\n\n /**\n * Called when the dialog is closed with a positive action.\n * Override this function to handle the positive action.\n * @param value The value passed to the dialog when it is closed.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected handlePositiveAction(value: unknown): void {\n this.finish()\n }\n\n /**\n * Override this method to handle the form submission.\n * @param e The submit event.\n */\n protected handleSubmit(e: SubmitEvent): void {\n e.preventDefault()\n }\n\n /**\n * The function called by the rendered when rendering this dialog.\n * This way, the `render()` function is still used as the primary template provider.\n */\n renderDialog(): TemplateResult {\n const classes = {\n activityDialog: true,\n [this.constructor.name.toLowerCase()]: true,\n ...this.dialogClasses,\n }\n return html`<ui-dialog modal .open=\"${this.opened}\" class=\"${classMap(classes)}\" @close=\"${this.handleDialogClosed}\"\n >${this.render()}</ui-dialog\n >`\n }\n\n /**\n * Used with dialogs that render forms. Override the `handleSubmit` method\n * to handle the form submission.\n * @param content The content to render in the form.\n * @param name Optional form name\n */\n protected renderForm(content: TemplateResult, name?: string): TemplateResult {\n if (!this.formId) {\n this.formId = `form-${this.constructor.name.toLowerCase()}`\n }\n return html`<form\n id=\"${this.formId}\"\n name=\"${ifDefined(name)}\"\n class=\"dialog-content\"\n @submit=\"${this.handleSubmit}\"\n >\n ${content}\n </form>`\n }\n\n /**\n * Renders the cancel button for the dialog.\n * @param label The label to use for the cancel button.\n */\n protected renderNegativeButton(init: ActionButtonInit = {}): TemplateResult {\n const { label = 'Cancel' } = init\n return html`<ui-text-button slot=\"button\" type=\"button\" value=\"dismiss\">${label}</ui-text-button>`\n }\n\n /**\n * Renders the submit button for the dialog.\n * If the formId is set, the button will be a submit button.\n * Otherwise, it will be a regular button.\n * @param label The label to use for the submit button.\n */\n protected renderPositiveButton(init: ActionButtonInit = {}): TemplateResult {\n const { label = 'OK', disabled = false } = init\n const { formId } = this\n const type = formId ? 'submit' : 'button'\n // UI buttons have a proper support for form association.\n return html`<ui-text-button\n slot=\"button\"\n ?disabled=\"${disabled}\"\n type=\"${type}\"\n value=\"confirm\"\n form=\"${ifDefined(formId)}\"\n >${label}</ui-text-button\n >`\n }\n\n /**\n * Renders the title for the dialog.\n * @param title The title to render in the dialog.\n */\n protected renderTitle(title: string): TemplateResult {\n return html`<span slot=\"title\">${title}</span>`\n }\n}\n"]}
package/eslint.config.js CHANGED
@@ -72,6 +72,9 @@ export default [
72
72
  'no-multi-spaces': ['error'],
73
73
  'no-console': ['error'],
74
74
  'no-redeclare': ['error'],
75
+ '@typescript-eslint/prefer-literal-enum-member': ['error', {
76
+ allowBitwiseExpressions: true,
77
+ }],
75
78
  },
76
79
  },
77
80
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api-client/ui",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Internal UI component library for the API Client ecosystem.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "build/src/index.js",