@hybridly/core 0.10.0-beta.17 → 0.10.0-beta.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -500,8 +500,7 @@ interface View {
500
500
  /** Deferred properties for this view. */
501
501
  deferred: Record<string, string | string[]>;
502
502
  /** Properties that should be merged with the existing payload. */
503
- mergeable: Array<[string, boolean, // true = prepend, false = append
504
- string | null]>;
503
+ mergeable: MergeableProperty[];
505
504
  }
506
505
  interface Dialog extends Required<View> {
507
506
  /** URL that is the base background view when navigating to the dialog directly. */
@@ -511,6 +510,8 @@ interface Dialog extends Required<View> {
511
510
  /** Unique identifier for this modal's lifecycle. */
512
511
  key: string;
513
512
  }
513
+ type MergeableProperty = [string, boolean, // true = prepend, false = append
514
+ string | null, string[]];
514
515
  type Property = null | string | number | boolean | Property[] | {
515
516
  [name: string]: Property;
516
517
  };
@@ -587,16 +588,6 @@ declare const router: {
587
588
  /** Creates the hybridly router. */
588
589
  declare function createRouter(options: RouterContextOptions): Promise<InternalRouterContext>;
589
590
  //#endregion
590
- //#region src/authorization.d.ts
591
- interface Authorizable<Authorizations extends Record<string, boolean>> {
592
- authorization: Authorizations;
593
- }
594
- /**
595
- * Checks whether the given data has the authorization for the given action.
596
- * If the data object has no authorization definition corresponding to the given action, this method will return `false`.
597
- */
598
- declare function can<Authorizations extends Record<string, boolean>, Data extends Authorizable<Authorizations>, Action extends keyof Data['authorization']>(resource: Data, action: Action): Authorizations[Action];
599
- //#endregion
600
591
  //#region src/routing/route.d.ts
601
592
  /**
602
593
  * Generates a route from the given route name.
@@ -649,4 +640,4 @@ declare const VERSION_HEADER = "x-hybrid-version";
649
640
  declare const ERROR_BAG_HEADER = "x-hybrid-error-bag";
650
641
  declare const SCROLL_REGION_ATTRIBUTE = "scroll-region";
651
642
  //#endregion
652
- export { type AsyncInterruptionScope, type Authorizable, type DynamicConfiguration, type Errors, type GlobalHybridlyProperties, type GlobalRouteCollection, type HttpClient, type HttpErrorCode, type HttpErrorKind, type HttpRequest, type HttpResponse, type HttpUploadProgressEvent, type HybridPayload, type HybridRequestOptions, MaybePromise, type Method, type NavigationResponse, type PendingHybridRequest, type Plugin, type Progress, type QueryArrayFormat, type RequestMode, type ResolveComponent, type RouteDefinition, type RouteName, type RouteParameters, type Router, type RouterContext, type RouterContextOptions, type RoutingConfiguration, type StringifyQueryOptions, type UrlResolvable, type Validation, can, constants_d_exports as constants, createRouter, createXhrHttpClient, definePlugin, getRouterContext, isHttpAbortError, isHttpError, makeUrl, parseQueryString, registerHook, route, router, sameUrls, stringifyQueryString };
643
+ export { type AsyncInterruptionScope, type DynamicConfiguration, type Errors, type GlobalHybridlyProperties, type GlobalRouteCollection, type HttpClient, type HttpErrorCode, type HttpErrorKind, type HttpRequest, type HttpResponse, type HttpUploadProgressEvent, type HybridPayload, type HybridRequestOptions, MaybePromise, type Method, type NavigationResponse, type PendingHybridRequest, type Plugin, type Progress, type QueryArrayFormat, type RequestMode, type ResolveComponent, type RouteDefinition, type RouteName, type RouteParameters, type Router, type RouterContext, type RouterContextOptions, type RoutingConfiguration, type StringifyQueryOptions, type UrlResolvable, type Validation, constants_d_exports as constants, createRouter, createXhrHttpClient, definePlugin, getRouterContext, isHttpAbortError, isHttpError, makeUrl, parseQueryString, registerHook, route, router, sameUrls, stringifyQueryString };
package/dist/index.mjs CHANGED
@@ -585,6 +585,9 @@ function createPromiseWithResolvers() {
585
585
  reject
586
586
  };
587
587
  }
588
+ function evaluateConditionalOption(options, option) {
589
+ return typeof option === "function" ? option(options) : option;
590
+ }
588
591
  //#endregion
589
592
  //#region src/router/request/request.ts
590
593
  function createPendingHybridRequest(options) {
@@ -709,13 +712,10 @@ async function navigate(options) {
709
712
  options.payload ??= payloadFromContext();
710
713
  options.payload.view ??= payloadFromContext().view;
711
714
  options.payload.view.properties = options.properties ?? options.payload.view.properties;
712
- function evaluateConditionalOption(option) {
713
- return typeof option === "function" ? option(options) : option;
714
- }
715
- const shouldPreserveState = evaluateConditionalOption(options.preserveState);
716
- const shouldPreserveScroll = evaluateConditionalOption(options.preserveScroll);
717
- const shouldReplaceHistory = evaluateConditionalOption(options.replace);
718
- const shouldReplaceUrl = evaluateConditionalOption(options.preserveUrl);
715
+ const shouldPreserveState = evaluateConditionalOption(options, options.preserveState);
716
+ const shouldPreserveScroll = evaluateConditionalOption(options, options.preserveScroll);
717
+ const shouldReplaceHistory = evaluateConditionalOption(options, options.replace);
718
+ const shouldReplaceUrl = evaluateConditionalOption(options, options.preserveUrl);
719
719
  const shouldPreserveView = !options.payload.view.component;
720
720
  if (shouldPreserveState && getHistoryMemo() && options.payload.view.component === context.view.component) {
721
721
  debug.history("Setting the memo from this history entry into the current context.");
@@ -888,7 +888,7 @@ async function handleHybridRequestResponse({ request, response }) {
888
888
  if (options.mode !== "async" || context.view.component === request.view.component) {
889
889
  const properties = (() => {
890
890
  if (!payload.view && !isPartial(options)) return;
891
- if (!payload.view.component || payload.view.component === context.view.component) return resolveProperties(context.view.properties, payload.view);
891
+ if (!payload.view.component || payload.view.component === context.view.component) return resolveProperties(context.view.properties, payload.view, { mergeWithOriginal: evaluateConditionalOption(options, options.preserveState) !== false });
892
892
  })();
893
893
  if (properties) debug.router("Merged properties:", properties);
894
894
  await navigate({
@@ -919,40 +919,53 @@ function isHybridResponse(response) {
919
919
  return response.headers.has(HYBRIDLY_HEADER);
920
920
  }
921
921
  function isPartial(options) {
922
- return options.only !== void 0 || options.except !== void 0;
923
- }
924
- function resolveProperties(original, payload) {
925
- const mergedPayloadProperties = merge(original, payload.properties);
926
- (payload.mergeable ?? []).forEach(([mergeableProperty, prepends, uniqueBy]) => {
927
- const originalValue = get(original, mergeableProperty);
928
- const newValue = get(payload.properties, mergeableProperty);
929
- const mergeArrays = (current, incoming) => {
930
- const merged = prepends === true ? [...incoming, ...current] : [...current, ...incoming];
931
- if (typeof uniqueBy !== "string") return merged;
932
- const getUniqueKey = (entry) => {
933
- const key = get(entry, uniqueBy);
934
- return key === void 0 ? Symbol() : key;
935
- };
936
- if (prepends === true) return uniqBy(merged, getUniqueKey);
937
- const orderedKeys = [];
938
- const valuesByKey = /* @__PURE__ */ new Map();
939
- for (const entry of merged) {
940
- const key = getUniqueKey(entry);
941
- if (!valuesByKey.has(key)) orderedKeys.push(key);
942
- valuesByKey.set(key, entry);
943
- }
944
- return orderedKeys.map((key) => valuesByKey.get(key));
945
- };
946
- let value = newValue;
947
- if (Array.isArray(originalValue)) value = mergeArrays(originalValue, Array.isArray(newValue) ? newValue : newValue === void 0 ? [] : [newValue]);
948
- else if (originalValue instanceof Object && newValue instanceof Object) value = merge(originalValue, newValue, {
949
- overwriteArray: false,
950
- arrayMerge: (current, incoming) => mergeArrays(current, incoming)
951
- });
952
- set(mergedPayloadProperties, mergeableProperty, value);
953
- });
922
+ return options.only !== void 0 || options.except !== void 0 || options.reset !== void 0;
923
+ }
924
+ function resolveProperties(original, payload, options) {
925
+ const mergeable = payload.mergeable ?? [];
926
+ const mergedPayloadProperties = options.mergeWithOriginal ? merge(original, payload.properties) : payload.properties;
927
+ for (const [property, shouldPrepend, uniqueBy, mergePaths] of mergeable) {
928
+ const originalValue = get(original, property);
929
+ const newValue = get(payload.properties, property);
930
+ if (!options.mergeWithOriginal && newValue === void 0) continue;
931
+ set(mergedPayloadProperties, property, mergeMergeableProperty(originalValue, newValue, get(mergedPayloadProperties, property), mergePaths, {
932
+ prepend: shouldPrepend,
933
+ uniqueBy
934
+ }));
935
+ }
954
936
  return mergedPayloadProperties;
955
937
  }
938
+ function mergeMergeableProperty(originalValue, newValue, currentValue, mergePaths, options) {
939
+ if (!mergePaths?.length) return mergeMergeableValue(originalValue, newValue, options);
940
+ const value = currentValue instanceof Object ? currentValue : {};
941
+ for (const mergePath of mergePaths) set(value, mergePath, mergeMergeableValue(get(originalValue, mergePath), get(newValue, mergePath), options));
942
+ return value;
943
+ }
944
+ function mergeMergeableValue(originalValue, newValue, options) {
945
+ if (Array.isArray(originalValue)) return mergeMergeableArrays(originalValue, Array.isArray(newValue) ? newValue : newValue === void 0 ? [] : [newValue], options);
946
+ if (originalValue instanceof Object && newValue instanceof Object) return merge(originalValue, newValue, {
947
+ overwriteArray: false,
948
+ arrayMerge: (current, incoming) => mergeMergeableArrays(current, incoming, options)
949
+ });
950
+ return newValue;
951
+ }
952
+ function mergeMergeableArrays(current, incoming, options) {
953
+ const merged = options.prepend ? [...incoming, ...current] : [...current, ...incoming];
954
+ if (typeof options.uniqueBy !== "string") return merged;
955
+ const getUniqueKey = (entry) => {
956
+ const key = get(entry, options.uniqueBy);
957
+ return key === void 0 ? Symbol() : key;
958
+ };
959
+ if (options.prepend) return uniqBy(merged, getUniqueKey);
960
+ const orderedKeys = [];
961
+ const valuesByKey = /* @__PURE__ */ new Map();
962
+ for (const entry of merged) {
963
+ const key = getUniqueKey(entry);
964
+ if (!valuesByKey.has(key)) orderedKeys.push(key);
965
+ valuesByKey.set(key, entry);
966
+ }
967
+ return orderedKeys.map((key) => valuesByKey.get(key));
968
+ }
956
969
  function mergeValidation(current, next, errorBag) {
957
970
  if (!errorBag) return next;
958
971
  return {
@@ -1592,13 +1605,4 @@ async function initializeRouter() {
1592
1605
  return context;
1593
1606
  }
1594
1607
  //#endregion
1595
- //#region src/authorization.ts
1596
- /**
1597
- * Checks whether the given data has the authorization for the given action.
1598
- * If the data object has no authorization definition corresponding to the given action, this method will return `false`.
1599
- */
1600
- function can(resource, action) {
1601
- return resource.authorization?.[action] ?? false;
1602
- }
1603
- //#endregion
1604
- export { can, constants_exports as constants, createRouter, createXhrHttpClient, definePlugin, getRouterContext, isHttpAbortError, isHttpError, makeUrl, parseQueryString, registerHook, route, router, sameUrls, stringifyQueryString };
1608
+ export { constants_exports as constants, createRouter, createXhrHttpClient, definePlugin, getRouterContext, isHttpAbortError, isHttpError, makeUrl, parseQueryString, registerHook, route, router, sameUrls, stringifyQueryString };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hybridly/core",
3
3
  "type": "module",
4
- "version": "0.10.0-beta.17",
4
+ "version": "0.10.0-beta.19",
5
5
  "description": "Core functionality of Hybridly",
6
6
  "author": "Enzo Innocenzi <enzo@innocenzi.dev>",
7
7
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  "build:stub": "obuild --stub"
41
41
  },
42
42
  "dependencies": {
43
- "@hybridly/utils": "0.10.0-beta.17",
43
+ "@hybridly/utils": "0.10.0-beta.19",
44
44
  "neoqs": "^6.13.0",
45
45
  "superjson": "^2.2.2",
46
46
  "es-toolkit": "^1.45.1"