@feasibleone/blong 1.15.0 → 1.16.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.16.1](https://github.com/feasibleone/blong/compare/blong-v1.16.0...blong-v1.16.1) (2026-04-10)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * build ([32951e4](https://github.com/feasibleone/blong/commit/32951e46561648651ee4e032545655007c05e274))
9
+
10
+ ## [1.16.0](https://github.com/feasibleone/blong/compare/blong-v1.15.0...blong-v1.16.0) (2026-04-10)
11
+
12
+
13
+ ### Features
14
+
15
+ * blong-ui ([9ca1281](https://github.com/feasibleone/blong/commit/9ca1281c0178c69dfc722bc4a5978f649bc1fa0d))
16
+
3
17
  ## [1.15.0](https://github.com/feasibleone/blong/compare/blong-v1.14.0...blong-v1.15.0) (2026-04-01)
4
18
 
5
19
 
package/dist/types.d.ts CHANGED
@@ -17625,6 +17625,22 @@ export type Config<T, C> = {
17625
17625
  logLevel: Parameters<ILog["logger"]>[0];
17626
17626
  namespace: string | string[];
17627
17627
  imports: string | RegExp | (string | RegExp)[];
17628
+ /**
17629
+ * Strip this many dot-separated namespace segments from the incoming method
17630
+ * name before looking up and calling a local handler. Useful when the
17631
+ * adapter handles a namespace prefix (e.g. `backend`) that must be removed
17632
+ * before the real handler name is used.
17633
+ *
17634
+ * Only applied when the method name does NOT contain a `/` separator
17635
+ * (the `/` form is auto-stripped by `methodPath` already).
17636
+ */
17637
+ stripNamespace?: number;
17638
+ /**
17639
+ * Prepend this namespace segment (dot-separated) to the outgoing method
17640
+ * name when dispatching. This is the dot-notation counterpart of the
17641
+ * existing `destination` field (which uses `/` as separator).
17642
+ */
17643
+ appendNamespace?: string;
17628
17644
  } & T;
17629
17645
  export type RemoteMethod = (...params: unknown[]) => Promise<unknown>;
17630
17646
  export interface IRemote {
@@ -18138,6 +18154,65 @@ export declare abstract class Internal {
18138
18154
  start(...params: unknown[]): Promise<unknown>;
18139
18155
  }
18140
18156
  export declare const handler: <T = Record<string, unknown>, C = AdapterContext>(definition: Definition<T, C>) => Definition<T, C>;
18157
+ /**
18158
+ * Browser-side equivalent of `handler`. Use this to define a component handler
18159
+ * in a realm's `component/` layer. Functionally identical to `handler` — the
18160
+ * distinction is semantic and makes intent clear in code review.
18161
+ *
18162
+ * The inner function should return a map whose keys are dot-notation method names
18163
+ * (e.g. `'coral.browse'`) and values are async functions that return component
18164
+ * metadata `{title, permission, icon, component: async () => ReactComponent}`.
18165
+ *
18166
+ * @example
18167
+ * ```ts
18168
+ * export default componentHandler(blong => function coralBrowse() {
18169
+ * return {
18170
+ * 'coral.browse': async () => ({
18171
+ * title: 'Browse Corals',
18172
+ * permission: 'marine.coral.browse',
18173
+ * component: async () => (await import('./CoralBrowse.js')).default,
18174
+ * }),
18175
+ * };
18176
+ * });
18177
+ * ```
18178
+ */
18179
+ export declare const componentHandler: <T = Record<string, unknown>, C = AdapterContext>(definition: Definition<T, C>) => Definition<T, C>;
18180
+ /** Action definition for use with `defineActions`. */
18181
+ export interface IActionDef {
18182
+ title?: string;
18183
+ permission?: string;
18184
+ icon?: string;
18185
+ /** Lazy-load a page component (page action). */
18186
+ component?: () => Promise<unknown>;
18187
+ /** Bus method name to invoke (query or mutation action). */
18188
+ method?: string;
18189
+ /** When true the action mutates data and should invalidate related caches. */
18190
+ mutates?: boolean;
18191
+ /** Action names whose query caches should be invalidated on success. */
18192
+ invalidates?: string[];
18193
+ /** Static params merged into every invocation. */
18194
+ params?: Record<string, unknown> | ((params: Record<string, unknown>) => Record<string, unknown>);
18195
+ }
18196
+ /**
18197
+ * Register action metadata for a realm's browser layer.
18198
+ *
18199
+ * Returns a handler-compatible function that the blong framework loads from
18200
+ * the realm's `actions/` or `action/` folder. Each entry in `actions` is
18201
+ * wrapped in a no-argument function so the framework can call it as a method.
18202
+ *
18203
+ * @example
18204
+ * ```ts
18205
+ * // marine/actions/index.ts
18206
+ * export default defineActions({
18207
+ * 'marine.coral.browse': {
18208
+ * title: 'Browse Corals',
18209
+ * permission: 'marine.coral.browse',
18210
+ * component: () => import('./components/CoralBrowse.js'),
18211
+ * },
18212
+ * });
18213
+ * ```
18214
+ */
18215
+ export declare const defineActions: (actions: Record<string, IActionDef>) => ((_blong: unknown) => Record<string, () => IActionDef>);
18141
18216
  export declare const library: <T = Record<string, unknown>>(definition: Lib<T>) => Lib<T>;
18142
18217
  export declare const validation: (validation: ValidationDefinition) => ValidationDefinition;
18143
18218
  export declare const api: (api: ApiDefinition) => ApiDefinition;
@@ -18154,6 +18229,8 @@ export type Kinds = "lib" | "validation" | "api" | "solution" | "server" | "brow
18154
18229
  export declare const kind: (what: {}) => Kinds | undefined;
18155
18230
  declare const _default: {
18156
18231
  handler: <T = Record<string, unknown>, C = AdapterContext>(definition: Definition<T, C>) => Definition<T, C>;
18232
+ componentHandler: <T = Record<string, unknown>, C = AdapterContext>(definition: Definition<T, C>) => Definition<T, C>;
18233
+ defineActions: (actions: Record<string, IActionDef>) => ((_blong: unknown) => Record<string, () => IActionDef>);
18157
18234
  library: <T = Record<string, unknown>>(definition: Lib<T>) => Lib<T>;
18158
18235
  validation: (validation: ValidationDefinition) => ValidationDefinition;
18159
18236
  api: (api: ApiDefinition) => ApiDefinition;
package/dist/types.js CHANGED
@@ -21,6 +21,49 @@ export class Internal {
21
21
  }
22
22
  }
23
23
  export const handler = (definition) => Object.defineProperty(definition, Kind, { value: 'handler' });
24
+ /**
25
+ * Browser-side equivalent of `handler`. Use this to define a component handler
26
+ * in a realm's `component/` layer. Functionally identical to `handler` — the
27
+ * distinction is semantic and makes intent clear in code review.
28
+ *
29
+ * The inner function should return a map whose keys are dot-notation method names
30
+ * (e.g. `'coral.browse'`) and values are async functions that return component
31
+ * metadata `{title, permission, icon, component: async () => ReactComponent}`.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * export default componentHandler(blong => function coralBrowse() {
36
+ * return {
37
+ * 'coral.browse': async () => ({
38
+ * title: 'Browse Corals',
39
+ * permission: 'marine.coral.browse',
40
+ * component: async () => (await import('./CoralBrowse.js')).default,
41
+ * }),
42
+ * };
43
+ * });
44
+ * ```
45
+ */
46
+ export const componentHandler = (definition) => Object.defineProperty(definition, Kind, { value: 'handler' });
47
+ /**
48
+ * Register action metadata for a realm's browser layer.
49
+ *
50
+ * Returns a handler-compatible function that the blong framework loads from
51
+ * the realm's `actions/` or `action/` folder. Each entry in `actions` is
52
+ * wrapped in a no-argument function so the framework can call it as a method.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * // marine/actions/index.ts
57
+ * export default defineActions({
58
+ * 'marine.coral.browse': {
59
+ * title: 'Browse Corals',
60
+ * permission: 'marine.coral.browse',
61
+ * component: () => import('./components/CoralBrowse.js'),
62
+ * },
63
+ * });
64
+ * ```
65
+ */
66
+ export const defineActions = (actions) => Object.defineProperty((_blong) => Object.fromEntries(Object.entries(actions).map(([key, value]) => [key, () => value])), Kind, { value: 'handler' });
24
67
  export const library = (definition) => Object.defineProperty(definition, Kind, { value: 'lib' });
25
68
  export const validation = (validation) => Object.defineProperty(validation, Kind, { value: 'validation' });
26
69
  export const api = (api) => Object.defineProperty(api, Kind, { value: 'api' });
@@ -41,6 +84,8 @@ export const orchestrator = (definition) => Object.defineProperty(definition, Ki
41
84
  export const kind = (what) => what[Kind];
42
85
  export default {
43
86
  handler,
87
+ componentHandler,
88
+ defineActions,
44
89
  library,
45
90
  validation,
46
91
  api,
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feasibleone/blong",
3
- "version": "1.15.0",
3
+ "version": "1.16.1",
4
4
  "description": "API and DRY focused RAD framework https://feasibleone.github.io/blong-docs",
5
5
  "keywords": [
6
6
  "blong",
@@ -23,7 +23,7 @@
23
23
  "ut-function.merge": "^1.5.6"
24
24
  },
25
25
  "devDependencies": {
26
- "@aws-sdk/client-s3": "^3.1003.0",
26
+ "@aws-sdk/client-s3": "^3.1028.0",
27
27
  "@keycloak/keycloak-admin-client": "^26.5.4",
28
28
  "@kubernetes/client-node": "^1.4.0",
29
29
  "@rushstack/eslint-config": "^4.6.4",
package/types.ts CHANGED
@@ -113,6 +113,22 @@ export type Config<T, C> = {
113
113
  logLevel: Parameters<ILog['logger']>[0];
114
114
  namespace: string | string[];
115
115
  imports: string | RegExp | (string | RegExp)[];
116
+ /**
117
+ * Strip this many dot-separated namespace segments from the incoming method
118
+ * name before looking up and calling a local handler. Useful when the
119
+ * adapter handles a namespace prefix (e.g. `backend`) that must be removed
120
+ * before the real handler name is used.
121
+ *
122
+ * Only applied when the method name does NOT contain a `/` separator
123
+ * (the `/` form is auto-stripped by `methodPath` already).
124
+ */
125
+ stripNamespace?: number;
126
+ /**
127
+ * Prepend this namespace segment (dot-separated) to the outgoing method
128
+ * name when dispatching. This is the dot-notation counterpart of the
129
+ * existing `destination` field (which uses `/` as separator).
130
+ */
131
+ appendNamespace?: string;
116
132
  } & T;
117
133
 
118
134
  export type RemoteMethod = (...params: unknown[]) => Promise<unknown>;
@@ -680,6 +696,81 @@ export abstract class Internal {
680
696
  export const handler = <T = Record<string, unknown>, C = AdapterContext>(
681
697
  definition: Definition<T, C>,
682
698
  ): Definition<T, C> => Object.defineProperty(definition, Kind, {value: 'handler'});
699
+
700
+ /**
701
+ * Browser-side equivalent of `handler`. Use this to define a component handler
702
+ * in a realm's `component/` layer. Functionally identical to `handler` — the
703
+ * distinction is semantic and makes intent clear in code review.
704
+ *
705
+ * The inner function should return a map whose keys are dot-notation method names
706
+ * (e.g. `'coral.browse'`) and values are async functions that return component
707
+ * metadata `{title, permission, icon, component: async () => ReactComponent}`.
708
+ *
709
+ * @example
710
+ * ```ts
711
+ * export default componentHandler(blong => function coralBrowse() {
712
+ * return {
713
+ * 'coral.browse': async () => ({
714
+ * title: 'Browse Corals',
715
+ * permission: 'marine.coral.browse',
716
+ * component: async () => (await import('./CoralBrowse.js')).default,
717
+ * }),
718
+ * };
719
+ * });
720
+ * ```
721
+ */
722
+ export const componentHandler = <T = Record<string, unknown>, C = AdapterContext>(
723
+ definition: Definition<T, C>,
724
+ ): Definition<T, C> => Object.defineProperty(definition, Kind, {value: 'handler'});
725
+
726
+ /** Action definition for use with `defineActions`. */
727
+ export interface IActionDef {
728
+ title?: string;
729
+ permission?: string;
730
+ icon?: string;
731
+ /** Lazy-load a page component (page action). */
732
+ component?: () => Promise<unknown>;
733
+ /** Bus method name to invoke (query or mutation action). */
734
+ method?: string;
735
+ /** When true the action mutates data and should invalidate related caches. */
736
+ mutates?: boolean;
737
+ /** Action names whose query caches should be invalidated on success. */
738
+ invalidates?: string[];
739
+ /** Static params merged into every invocation. */
740
+ params?: Record<string, unknown> | ((params: Record<string, unknown>) => Record<string, unknown>);
741
+ }
742
+
743
+ /**
744
+ * Register action metadata for a realm's browser layer.
745
+ *
746
+ * Returns a handler-compatible function that the blong framework loads from
747
+ * the realm's `actions/` or `action/` folder. Each entry in `actions` is
748
+ * wrapped in a no-argument function so the framework can call it as a method.
749
+ *
750
+ * @example
751
+ * ```ts
752
+ * // marine/actions/index.ts
753
+ * export default defineActions({
754
+ * 'marine.coral.browse': {
755
+ * title: 'Browse Corals',
756
+ * permission: 'marine.coral.browse',
757
+ * component: () => import('./components/CoralBrowse.js'),
758
+ * },
759
+ * });
760
+ * ```
761
+ */
762
+ export const defineActions = (
763
+ actions: Record<string, IActionDef>,
764
+ ): ((_blong: unknown) => Record<string, () => IActionDef>) =>
765
+ Object.defineProperty(
766
+ (_blong: unknown) =>
767
+ Object.fromEntries(
768
+ Object.entries(actions).map(([key, value]) => [key, () => value]),
769
+ ),
770
+ Kind,
771
+ {value: 'handler'},
772
+ );
773
+
683
774
  export const library = <T = Record<string, unknown>>(definition: Lib<T>): Lib<T> =>
684
775
  Object.defineProperty(definition, Kind, {value: 'lib'});
685
776
  export const validation = (validation: ValidationDefinition): ValidationDefinition =>
@@ -736,6 +827,8 @@ export const kind = (what: {[Kind]: Kinds | undefined}): Kinds | undefined => wh
736
827
 
737
828
  export default {
738
829
  handler,
830
+ componentHandler,
831
+ defineActions,
739
832
  library,
740
833
  validation,
741
834
  api,