@blotch/angular-lynx 22.2.6 → 22.2.8

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,6 +1,6 @@
1
1
  import { n as GestureState, r as GestureType, t as FlingDirection } from "./blotch-angular-lynx-const-MkK6UdZ7.mjs";
2
2
  import * as i0 from "@angular/core";
3
- import { ApplicationRef, Component, DOCUMENT, DestroyRef, Directive, ElementRef, EnvironmentInjector, ErrorHandler, Injectable, InjectionToken, Injector, LOCALE_ID, Renderer2, RendererFactory2, RendererStyleFlags2, TemplateRef, ViewContainerRef, ViewEncapsulation, computed, contentChild, createComponent, effect, forwardRef, inject, input, makeEnvironmentProviders, output, provideEnvironmentInitializer, signal, viewChild, ɵɵreplaceMetadata } from "@angular/core";
3
+ import { ApplicationRef, Component, DOCUMENT, DestroyRef, Directive, ElementRef, EnvironmentInjector, ErrorHandler, Injectable, InjectionToken, Injector, LOCALE_ID, Renderer2, RendererFactory2, RendererStyleFlags2, TemplateRef, ViewContainerRef, ViewEncapsulation, computed, contentChild, createComponent, effect, forwardRef, inject, input, makeEnvironmentProviders, output, provideEnvironmentInitializer, reflectComponentType, signal, viewChild, ɵɵreplaceMetadata } from "@angular/core";
4
4
  import { ReplaySubject, Subject, firstValueFrom } from "rxjs";
5
5
  import { APP_BASE_HREF, IMAGE_CONFIG, Location, LocationStrategy, PlatformLocation, getLocaleId } from "@angular/common";
6
6
  import { NG_VALUE_ACCESSOR } from "@angular/forms";
@@ -58,6 +58,7 @@ const isUtf8Text = (contentType) => {
58
58
  const charset = /;\s*charset="?([^";]+)/.exec(type)?.[1];
59
59
  return TEXT_TYPE.test(type) && (charset === void 0 || /^utf-?8$/.test(charset));
60
60
  };
61
+ const canonicalName = (name) => name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("-");
61
62
  const decodeBody = (body) => {
62
63
  if (body === null) return void 0;
63
64
  if ("text" in body) return body.text;
@@ -74,15 +75,16 @@ const fetchForMainThread = async (id, request) => {
74
75
  const response = await fetchImpl(request.url, {
75
76
  ...request.options,
76
77
  method: request.method,
77
- headers: Object.fromEntries(request.headers),
78
+ headers: Object.fromEntries(request.headers.map(([name, value]) => [canonicalName(name), value])),
78
79
  body: decodeBody(request.body),
79
80
  signal: controller.signal
80
81
  });
81
82
  const headers = [];
82
83
  response.headers.forEach((value, name) => headers.push([name, value]));
83
84
  if (response.status === LYNX_FAILURE_STATUS && headers.length === 0) throw new TypeError(response.statusText || "Network request failed");
85
+ const contentType = headers.find(([name]) => name.toLowerCase() === "content-type")?.[1] ?? null;
84
86
  let body = null;
85
- if (!NULL_BODY_STATUSES.has(response.status)) body = isUtf8Text(response.headers.get("content-type")) ? { text: await response.text() } : { base64: bytesToBase64(new Uint8Array(await response.arrayBuffer())) };
87
+ if (!NULL_BODY_STATUSES.has(response.status)) body = isUtf8Text(contentType) ? { text: await response.text() } : { base64: bytesToBase64(new Uint8Array(await response.arrayBuffer())) };
86
88
  return {
87
89
  status: response.status,
88
90
  statusText: response.statusText,
@@ -239,6 +241,12 @@ const handlers = {
239
241
  if (typeof fn !== "function") throw new Error(`${kind === "native" ? "NativeModules" : "lynx.getJSModule"}: ${name}.${method} is not available`);
240
242
  return fn.apply(module, restoreFunctions(args));
241
243
  },
244
+ callNativeModuleAsync: (name, method, args) => new Promise((resolve) => {
245
+ const module = findModule("native", name);
246
+ const fn = module?.[method];
247
+ if (typeof fn !== "function") throw new Error(`NativeModules: ${name}.${method} is not available`);
248
+ fn.call(module, ...args, (result) => resolve(result));
249
+ }),
242
250
  registerJSModule: (name, module) => {
243
251
  lynxApi("registerModule")(name, restoreFunctions(module));
244
252
  },
@@ -254,6 +262,7 @@ const callOnBackground = (name, ...args) => {
254
262
  } catch (error) {
255
263
  return Promise.reject(error);
256
264
  }
265
+ listenInTestingEnvironment();
257
266
  return new Promise((resolve, reject) => {
258
267
  const id = nextCallId++;
259
268
  pending.set(id, {
@@ -308,60 +317,74 @@ const unsubscribeSessionStorageFromMainThread = (relayId) => {
308
317
  if (!sessionStorageListeners.delete(relayId)) return;
309
318
  callOnBackground("unsubscribeSessionStorage", relayId).catch(() => {});
310
319
  };
311
- const installRelay = () => {
312
- if (typeof lynx === "undefined") return;
313
- try {
314
- if (isMainThread()) {
315
- const context = lynx.getJSContext();
316
- context.addEventListener(RESULT_EVENT, (event) => {
317
- const { id, value, error } = JSON.parse(event.data);
318
- const call = pending.get(id);
319
- if (!call) return;
320
- pending.delete(id);
321
- if (error !== void 0) call.reject(new Error(error));
322
- else call.resolve(value);
323
- });
324
- context.addEventListener(SESSION_STORAGE_EVENT, (event) => {
325
- const { relayId, value } = JSON.parse(event.data);
326
- sessionStorageListeners.get(relayId)?.(value);
327
- });
328
- context.addEventListener(CALLBACK_EVENT, (event) => {
329
- const { id, args } = JSON.parse(event.data);
330
- relayedFunctions.get(id)?.(...args);
331
- });
332
- return;
320
+ const relayContexts = /* @__PURE__ */ new WeakSet();
321
+ const listenOnMainThread = (context) => {
322
+ if (relayContexts.has(context)) return;
323
+ relayContexts.add(context);
324
+ context.addEventListener(RESULT_EVENT, (event) => {
325
+ const { id, value, error } = JSON.parse(event.data);
326
+ const call = pending.get(id);
327
+ if (!call) return;
328
+ pending.delete(id);
329
+ if (error !== void 0) call.reject(new Error(error));
330
+ else call.resolve(value);
331
+ });
332
+ context.addEventListener(SESSION_STORAGE_EVENT, (event) => {
333
+ const { relayId, value } = JSON.parse(event.data);
334
+ sessionStorageListeners.get(relayId)?.(value);
335
+ });
336
+ context.addEventListener(CALLBACK_EVENT, (event) => {
337
+ const { id, args } = JSON.parse(event.data);
338
+ relayedFunctions.get(id)?.(...args);
339
+ });
340
+ };
341
+ const listenOnBackgroundThread = (context) => {
342
+ if (relayContexts.has(context)) return;
343
+ relayContexts.add(context);
344
+ context.addEventListener(CALL_EVENT, async (event) => {
345
+ const { id, name, args } = JSON.parse(event.data);
346
+ let reply;
347
+ try {
348
+ const handler = handlers[name];
349
+ if (!handler) throw new Error(`Unknown background call: ${name}`);
350
+ reply = {
351
+ id,
352
+ value: await handler(...args)
353
+ };
354
+ } catch (error) {
355
+ reply = {
356
+ id,
357
+ error: error instanceof Error ? error.message : String(error)
358
+ };
333
359
  }
334
- const context = lynx.getCoreContext();
335
- context.addEventListener(CALL_EVENT, async (event) => {
336
- const { id, name, args } = JSON.parse(event.data);
337
- let reply;
338
- try {
339
- const handler = handlers[name];
340
- if (!handler) throw new Error(`Unknown background call: ${name}`);
341
- reply = {
342
- id,
343
- value: await handler(...args)
344
- };
345
- } catch (error) {
346
- reply = {
347
- id,
348
- error: error instanceof Error ? error.message : String(error)
349
- };
350
- }
351
- let data;
352
- try {
353
- data = JSON.stringify(reply);
354
- } catch (error) {
355
- data = JSON.stringify({
356
- id,
357
- error: `The result of ${name} can't be sent to the main thread: ${error.message}`
358
- });
359
- }
360
- context.dispatchEvent({
361
- type: RESULT_EVENT,
362
- data
360
+ let data;
361
+ try {
362
+ data = JSON.stringify(reply);
363
+ } catch (error) {
364
+ data = JSON.stringify({
365
+ id,
366
+ error: `The result of ${name} can't be sent to the main thread: ${error.message}`
363
367
  });
368
+ }
369
+ context.dispatchEvent({
370
+ type: RESULT_EVENT,
371
+ data
364
372
  });
373
+ });
374
+ };
375
+ const listenInTestingEnvironment = () => {
376
+ const env = globalThis.lynxTestingEnv;
377
+ if (!env) return;
378
+ try {
379
+ listenOnMainThread(lynx.getJSContext());
380
+ listenOnBackgroundThread(env.backgroundThread.globalThis.lynx.getCoreContext());
381
+ } catch {}
382
+ };
383
+ const installRelay = () => {
384
+ if (typeof lynx === "undefined") return;
385
+ try {
386
+ if (isMainThread()) listenOnMainThread(lynx.getJSContext());
387
+ else listenOnBackgroundThread(lynx.getCoreContext());
365
388
  } catch {}
366
389
  };
367
390
  installRelay();
@@ -5292,6 +5315,170 @@ i0.ɵɵngDeclareClassMetadata({
5292
5315
  args: [{ providedIn: "root" }]
5293
5316
  }]
5294
5317
  });
5318
+ var NoModuleError = class extends Error {};
5319
+ const nativeStore = (module) => {
5320
+ const call = async (method, args) => {
5321
+ let result;
5322
+ try {
5323
+ result = await callOnBackground("callNativeModuleAsync", module, method, args);
5324
+ } catch (error) {
5325
+ throw new NoModuleError(error.message);
5326
+ }
5327
+ if (result?.error !== void 0) throw new Error(result.error);
5328
+ return result?.value ?? null;
5329
+ };
5330
+ return {
5331
+ getItem: (key) => call("getItem", [key]),
5332
+ setItem: async (key, value) => {
5333
+ await call("setItem", [key, value]);
5334
+ },
5335
+ removeItem: async (key) => {
5336
+ await call("removeItem", [key]);
5337
+ },
5338
+ clear: async () => {
5339
+ await call("clear", []);
5340
+ }
5341
+ };
5342
+ };
5343
+ const browserStore = (storage, prefix) => ({
5344
+ getItem: async (key) => storage.getItem(prefix + key),
5345
+ setItem: async (key, value) => storage.setItem(prefix + key, value),
5346
+ removeItem: async (key) => storage.removeItem(prefix + key),
5347
+ clear: async () => {
5348
+ const keys = [];
5349
+ for (let i = 0; i < storage.length; i++) {
5350
+ const key = storage.key(i);
5351
+ if (key?.startsWith(prefix)) keys.push(key);
5352
+ }
5353
+ for (const key of keys) storage.removeItem(key);
5354
+ }
5355
+ });
5356
+ const memoryStore = () => {
5357
+ const values = /* @__PURE__ */ new Map();
5358
+ return {
5359
+ getItem: async (key) => values.get(key) ?? null,
5360
+ setItem: async (key, value) => {
5361
+ values.set(key, value);
5362
+ },
5363
+ removeItem: async (key) => {
5364
+ values.delete(key);
5365
+ },
5366
+ clear: async () => values.clear()
5367
+ };
5368
+ };
5369
+ const browserStorage = () => {
5370
+ if (typeof SystemInfo === "undefined" || SystemInfo.platform !== "web") return;
5371
+ try {
5372
+ return globalThis.localStorage;
5373
+ } catch {
5374
+ return;
5375
+ }
5376
+ };
5377
+ const decode = (raw) => {
5378
+ try {
5379
+ return JSON.parse(raw);
5380
+ } catch {
5381
+ return raw;
5382
+ }
5383
+ };
5384
+ var PersistentStorage = class {
5385
+ #native;
5386
+ #webPrefix;
5387
+ #memory = memoryStore();
5388
+ #hasModule = true;
5389
+ constructor(module, webPrefix) {
5390
+ this.#native = nativeStore(module);
5391
+ this.#webPrefix = webPrefix;
5392
+ }
5393
+ async getItem(key) {
5394
+ const raw = await this.#run((store) => store.getItem(key));
5395
+ return raw === null ? null : decode(raw);
5396
+ }
5397
+ async setItem(key, value) {
5398
+ const raw = JSON.stringify(value);
5399
+ if (raw === void 0) throw new TypeError(`Can't store a ${typeof value} under "${key}": values are stored as JSON.`);
5400
+ await this.#run((store) => store.setItem(key, raw));
5401
+ }
5402
+ async removeItem(key) {
5403
+ await this.#run((store) => store.removeItem(key));
5404
+ }
5405
+ async clear() {
5406
+ await this.#run((store) => store.clear());
5407
+ }
5408
+ async #run(operation) {
5409
+ const web = browserStorage();
5410
+ if (web) return operation(browserStore(web, this.#webPrefix));
5411
+ if (this.#hasModule) try {
5412
+ return await operation(this.#native);
5413
+ } catch (error) {
5414
+ if (!(error instanceof NoModuleError)) throw error;
5415
+ this.#hasModule = false;
5416
+ }
5417
+ return operation(this.#memory);
5418
+ }
5419
+ };
5420
+ var LynxLocalStorage = class LynxLocalStorage extends PersistentStorage {
5421
+ constructor() {
5422
+ super("AngularLynxLocalStorage", "angular-lynx:");
5423
+ }
5424
+ static ɵfac = i0.ɵɵngDeclareFactory({
5425
+ minVersion: "12.0.0",
5426
+ version: "22.2.1",
5427
+ ngImport: i0,
5428
+ type: LynxLocalStorage,
5429
+ deps: [],
5430
+ target: i0.ɵɵFactoryTarget.Injectable
5431
+ });
5432
+ static ɵprov = i0.ɵɵngDeclareInjectable({
5433
+ minVersion: "12.0.0",
5434
+ version: "22.2.1",
5435
+ ngImport: i0,
5436
+ type: LynxLocalStorage,
5437
+ providedIn: "root"
5438
+ });
5439
+ };
5440
+ i0.ɵɵngDeclareClassMetadata({
5441
+ minVersion: "12.0.0",
5442
+ version: "22.2.1",
5443
+ ngImport: i0,
5444
+ type: LynxLocalStorage,
5445
+ decorators: [{
5446
+ type: Injectable,
5447
+ args: [{ providedIn: "root" }]
5448
+ }],
5449
+ ctorParameters: () => []
5450
+ });
5451
+ var LynxSecureStorage = class LynxSecureStorage extends PersistentStorage {
5452
+ constructor() {
5453
+ super("AngularLynxSecureStorage", "angular-lynx-secure:");
5454
+ }
5455
+ static ɵfac = i0.ɵɵngDeclareFactory({
5456
+ minVersion: "12.0.0",
5457
+ version: "22.2.1",
5458
+ ngImport: i0,
5459
+ type: LynxSecureStorage,
5460
+ deps: [],
5461
+ target: i0.ɵɵFactoryTarget.Injectable
5462
+ });
5463
+ static ɵprov = i0.ɵɵngDeclareInjectable({
5464
+ minVersion: "12.0.0",
5465
+ version: "22.2.1",
5466
+ ngImport: i0,
5467
+ type: LynxSecureStorage,
5468
+ providedIn: "root"
5469
+ });
5470
+ };
5471
+ i0.ɵɵngDeclareClassMetadata({
5472
+ minVersion: "12.0.0",
5473
+ version: "22.2.1",
5474
+ ngImport: i0,
5475
+ type: LynxSecureStorage,
5476
+ decorators: [{
5477
+ type: Injectable,
5478
+ args: [{ providedIn: "root" }]
5479
+ }],
5480
+ ctorParameters: () => []
5481
+ });
5295
5482
  var LynxTextMeasure = class LynxTextMeasure {
5296
5483
  measure(text, options) {
5297
5484
  if (typeof lynx === "undefined" || typeof lynx.getTextInfo !== "function") throw new Error("lynx.getTextInfo is not available in this environment");
@@ -5923,6 +6110,14 @@ i0.ɵɵngDeclareClassMetadata({
5923
6110
  args: [{ providedIn: "root" }]
5924
6111
  }]
5925
6112
  });
6113
+ const hostElements = /* @__PURE__ */ new Map();
6114
+ const ELEMENT_SELECTOR = /^[a-z][\w-]*$/i;
6115
+ const registerHostElement = (component, element) => {
6116
+ const tags = (reflectComponentType(component)?.selector ?? "").split(",").map((part) => part.trim()).filter((part) => ELEMENT_SELECTOR.test(part));
6117
+ if (tags.length === 0) throw new Error(`registerHostElement: ${component.name} isn't a component with an element selector, such as 'app-title'.`);
6118
+ for (const tag of tags) hostElements.set(tag, element);
6119
+ };
6120
+ const hostElementOf = (tag) => hostElements.get(tag) ?? tag;
5926
6121
  const createListElement = (pageId) => {
5927
6122
  let listEl;
5928
6123
  const componentAtIndex = (listRef, listId, cellIndex, opId) => {
@@ -6000,7 +6195,8 @@ var LynxDocument = class {
6000
6195
  setPageElementRef(pageElement);
6001
6196
  return this.page;
6002
6197
  }
6003
- createElement(tag, value) {
6198
+ createElement(name, value) {
6199
+ const tag = hostElementOf(name);
6004
6200
  /* v8 ignore next */
6005
6201
  if (__PROFILE__) devStats.elementCreated++;
6006
6202
  scheduleSettleFlush();
@@ -6070,7 +6266,7 @@ var LynxHydrateDocument = class {
6070
6266
  if (!this.#isHydrating()) return this.#getFallback().createElement(tag, value);
6071
6267
  if (tag === "page") return this.#page;
6072
6268
  const el = this.#nextElement();
6073
- el.tagName = tag;
6269
+ el.tagName = hostElementOf(tag);
6074
6270
  return el;
6075
6271
  }
6076
6272
  createText(value) {
@@ -8611,6 +8807,6 @@ const bootstrapOnMainThread = async (rootComponent, options) => {
8611
8807
  if (__WEB__ && !wasHydrating) setTimeout(() => __FlushElementTree(), 0);
8612
8808
  return appRef;
8613
8809
  };
8614
- export { BaseGesture, ComposedGesture, ContinuousGesture, DYNAMIC_COLOR_ROLES, FlingDirection, FlingGesture, Gesture, GestureState, GestureStateManager, GestureType, LYNX_ELEMENTS, LYNX_FORM_ACCESSORS, LongPressGesture, LynxAccessibility, LynxAccessibilitySettings, LynxAccessibilityTraits, LynxAnimation, LynxBlock, LynxBlurView, LynxCoverView, LynxDevTools, LynxErrorHandler, LynxExposure, LynxFont, LynxFor, LynxFrame, LynxGestureDetector, LynxGlobalData, LynxGlobalExposure, LynxIf, LynxImage, LynxInitData, LynxInlineTruncation, LynxInput, LynxInputValueAccessor, LynxList, LynxListItem, LynxLocale, LynxLocationStrategy, LynxLogger, LynxMainThread, LynxMainThreadEvent, LynxNativeModule, LynxOverlay, LynxPerformance, LynxPlatformLocation, LynxPortal, LynxRefresh, LynxRefreshHeader, LynxResourcePrefetch, LynxRouteReuseStrategy, LynxRouterLinkActive, LynxSafeArea, LynxScrollCoordinator, LynxScrollCoordinatorHeader, LynxScrollCoordinatorSlot, LynxScrollCoordinatorSlotDrag, LynxScrollCoordinatorToolbar, LynxScrollView, LynxSessionStorage, LynxSvg, LynxSystemInfo, LynxText, LynxTextMeasure, LynxTextarea, LynxTextareaValueAccessor, LynxTheme, LynxTitleBarView, LynxTransition, LynxTransitionGroup, LynxVideo, LynxView, LynxViewPager, LynxViewPagerItem, LynxWebAuthSession, LynxWebView, MainThreadElement, MainThreadRef, PanGesture, PinchGesture, PortalRef, RotationGesture, SAFE_AREA_INSET_BOTTOM, SAFE_AREA_INSET_LEFT, SAFE_AREA_INSET_RIGHT, SAFE_AREA_INSET_TOP, TapGesture, WebAuthSessionError, backgroundFn, bootstrapApplication, createMainThreadRef, getLynxAppLocale, loadLazyBundle, mainThreadFn, provideLocale, provideRenderer, provideRouter, registerDataProcessors, ɵhmrAccept, ɵstartBackgroundThread };
8810
+ export { BaseGesture, ComposedGesture, ContinuousGesture, DYNAMIC_COLOR_ROLES, FlingDirection, FlingGesture, Gesture, GestureState, GestureStateManager, GestureType, LYNX_ELEMENTS, LYNX_FORM_ACCESSORS, LongPressGesture, LynxAccessibility, LynxAccessibilitySettings, LynxAccessibilityTraits, LynxAnimation, LynxBlock, LynxBlurView, LynxCoverView, LynxDevTools, LynxErrorHandler, LynxExposure, LynxFont, LynxFor, LynxFrame, LynxGestureDetector, LynxGlobalData, LynxGlobalExposure, LynxIf, LynxImage, LynxInitData, LynxInlineTruncation, LynxInput, LynxInputValueAccessor, LynxList, LynxListItem, LynxLocalStorage, LynxLocale, LynxLocationStrategy, LynxLogger, LynxMainThread, LynxMainThreadEvent, LynxNativeModule, LynxOverlay, LynxPerformance, LynxPlatformLocation, LynxPortal, LynxRefresh, LynxRefreshHeader, LynxResourcePrefetch, LynxRouteReuseStrategy, LynxRouterLinkActive, LynxSafeArea, LynxScrollCoordinator, LynxScrollCoordinatorHeader, LynxScrollCoordinatorSlot, LynxScrollCoordinatorSlotDrag, LynxScrollCoordinatorToolbar, LynxScrollView, LynxSecureStorage, LynxSessionStorage, LynxSvg, LynxSystemInfo, LynxText, LynxTextMeasure, LynxTextarea, LynxTextareaValueAccessor, LynxTheme, LynxTitleBarView, LynxTransition, LynxTransitionGroup, LynxVideo, LynxView, LynxViewPager, LynxViewPagerItem, LynxWebAuthSession, LynxWebView, MainThreadElement, MainThreadRef, PanGesture, PinchGesture, PortalRef, RotationGesture, SAFE_AREA_INSET_BOTTOM, SAFE_AREA_INSET_LEFT, SAFE_AREA_INSET_RIGHT, SAFE_AREA_INSET_TOP, TapGesture, WebAuthSessionError, backgroundFn, bootstrapApplication, createMainThreadRef, getLynxAppLocale, loadLazyBundle, mainThreadFn, provideLocale, provideRenderer, provideRouter, registerDataProcessors, registerHostElement, ɵhmrAccept, ɵstartBackgroundThread };
8615
8811
 
8616
8812
  //# sourceMappingURL=blotch-angular-lynx.mjs.map