@feasibleone/blong 1.13.0 → 1.15.0

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,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.15.0](https://github.com/feasibleone/blong/compare/blong-v1.14.0...blong-v1.15.0) (2026-04-01)
4
+
5
+
6
+ ### Features
7
+
8
+ * implement ConfigRuntime for hot configuration reload ([#115](https://github.com/feasibleone/blong/issues/115)) ([61bab7c](https://github.com/feasibleone/blong/commit/61bab7ce8587bf83d72fe80138aaef68943f21c4))
9
+ * unified test and handlers ([#117](https://github.com/feasibleone/blong/issues/117)) ([bf0ed96](https://github.com/feasibleone/blong/commit/bf0ed96c5df3d949fa225dd8a30fc25698a7855a))
10
+
11
+ ## [1.14.0](https://github.com/feasibleone/blong/compare/blong-v1.13.0...blong-v1.14.0) (2026-03-29)
12
+
13
+
14
+ ### Features
15
+
16
+ * built-in REST-FS server component for remote filesystem over Gateway ([#108](https://github.com/feasibleone/blong/issues/108)) ([352ef2a](https://github.com/feasibleone/blong/commit/352ef2a86a4da1f29eaf931c6057d018918fedaf))
17
+
3
18
  ## [1.13.0](https://github.com/feasibleone/blong/compare/blong-v1.12.4...blong-v1.13.0) (2026-03-29)
4
19
 
5
20
 
package/dist/types.d.ts CHANGED
@@ -17640,6 +17640,7 @@ export interface IRpcServer {
17640
17640
  unregister: (methods: string[], namespace: string, reply: boolean) => void;
17641
17641
  start: () => Promise<IRpcServer>;
17642
17642
  stop: () => Promise<IRpcServer>;
17643
+ setAttachCheckpoint?: (fn: ((meta: IMeta) => void) | undefined) => void;
17643
17644
  }
17644
17645
  export interface ILocal {
17645
17646
  register: (methods: object, namespace: string, reply: boolean, pkg: {
@@ -17663,6 +17664,7 @@ export interface IGateway {
17663
17664
  name: string;
17664
17665
  version: string;
17665
17666
  }) => void;
17667
+ registerPlugin: (plugin: unknown, options?: unknown) => void;
17666
17668
  start: () => Promise<IGateway>;
17667
17669
  stop: () => Promise<IGateway>;
17668
17670
  }
@@ -17682,6 +17684,7 @@ export interface IRegistry {
17682
17684
  methods: Map<string, Handlers>;
17683
17685
  modules: Map<string | symbol, IRegistry[]>;
17684
17686
  createPort: (id: string) => Promise<ReturnType<IAdapterFactory>>;
17687
+ getPort: (id: string) => ReturnType<IAdapterFactory> | undefined;
17685
17688
  replaceHandlers: (id: string, handlers: object) => Promise<void>;
17686
17689
  loadApi: (id: string, def: {
17687
17690
  namespace: Record<string, string | string[]>;
@@ -17724,6 +17727,7 @@ export interface IApi {
17724
17727
  utLog: {
17725
17728
  createLog: ILog["logger"];
17726
17729
  };
17730
+ attachCheckpoint?: (meta: IMeta) => void;
17727
17731
  handlers?: (api: {
17728
17732
  utError: IError;
17729
17733
  remote: IRemote;
@@ -17800,6 +17804,21 @@ export interface IAdapter<T, C> {
17800
17804
  waiting: unknown;
17801
17805
  buffer: unknown;
17802
17806
  }) => void;
17807
+ /**
17808
+ * Optional lifecycle hook called when configuration changes.
17809
+ * When present, the framework calls this instead of a full stop+start cycle.
17810
+ * The adapter should inspect `diff` and only recreate the resources that
17811
+ * actually changed (e.g. destroy and rebuild the DB connection pool when
17812
+ * the `knex` sub-key is in the diff, but leave everything else intact).
17813
+ *
17814
+ * @param diff Flat map of dotted config paths to `{prev, next}` pairs
17815
+ * @param next The full new effective config snapshot (via proxy)
17816
+ * @param prev The full previous effective config snapshot
17817
+ */
17818
+ configChanged?: (diff: Map<string, {
17819
+ prev: unknown;
17820
+ next: unknown;
17821
+ }>, next: object, prev: object) => Promise<void>;
17803
17822
  }
17804
17823
  export interface IAdapterFactory<T = Record<string, unknown>, C = Record<string, unknown>> {
17805
17824
  config?: Config<T, C> | false;
@@ -17877,6 +17896,13 @@ export interface IMeta {
17877
17896
  };
17878
17897
  gateway?: object;
17879
17898
  validation?: unknown;
17899
+ name?: string;
17900
+ checkpoint?: CheckpointFn;
17901
+ checkpoints?: Array<{
17902
+ name: string;
17903
+ data?: unknown;
17904
+ timestamp: number;
17905
+ }>;
17880
17906
  }
17881
17907
  export type HRTime = [
17882
17908
  number,
@@ -18000,18 +18026,22 @@ export type ThenableProxy = Promise<unknown> & {
18000
18026
  export type ChainStep = ((assert: typeof Assert, context: {
18001
18027
  $meta: IMeta;
18002
18028
  } & Record<string, Promise<unknown[]> & ThenableProxy>) => Promise<object>) | object;
18029
+ export type CheckpointFn = (this: IMeta, name: string, data?: unknown) => void;
18003
18030
  export interface ILib {
18004
18031
  type: typeof Type;
18005
18032
  error: <T>(errors: T) => Record<keyof T, (params?: unknown, $meta?: IMeta) => ITypedError>;
18006
18033
  rename: <T extends object>(object: T, name: string) => T & {
18007
18034
  name: string;
18008
18035
  };
18036
+ /** @deprecated The framework now auto-names step arrays from handler names. */
18009
18037
  group: (name: string) => (handlers: ChainStep[]) => ChainStep[] & {
18010
18038
  name: string;
18011
18039
  };
18040
+ assert: typeof Assert | undefined;
18012
18041
  ulid: () => string;
18013
18042
  uuid4: () => string;
18014
18043
  uuid7: () => string;
18044
+ setProperty: (obj: Record<string, unknown>, path: string, value: unknown) => void;
18015
18045
  merge<T, S1>(target: T, source: S1): T & S1;
18016
18046
  merge<T, S1, S2>(target: T, source1: S1, source2: S2): T & S1 & S2;
18017
18047
  merge<T, S1, S2, S3>(target: T, source1: S1, source2: S2, source3: S3): T & S1 & S2 & S3;
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.13.0",
3
+ "version": "1.15.0",
4
4
  "description": "API and DRY focused RAD framework https://feasibleone.github.io/blong-docs",
5
5
  "keywords": [
6
6
  "blong",
package/types.ts CHANGED
@@ -128,6 +128,7 @@ export interface IRpcServer {
128
128
  unregister: (methods: string[], namespace: string, reply: boolean) => void;
129
129
  start: () => Promise<IRpcServer>;
130
130
  stop: () => Promise<IRpcServer>;
131
+ setAttachCheckpoint?: (fn: ((meta: IMeta) => void) | undefined) => void;
131
132
  }
132
133
 
133
134
  export interface ILocal {
@@ -150,6 +151,7 @@ export interface IGateway {
150
151
  validations: Record<string, GatewaySchema>,
151
152
  pkg: {name: string; version: string},
152
153
  ) => void;
154
+ registerPlugin: (plugin: unknown, options?: unknown) => void;
153
155
  start: () => Promise<IGateway>;
154
156
  stop: () => Promise<IGateway>;
155
157
  }
@@ -171,6 +173,7 @@ export interface IRegistry {
171
173
  methods: Map<string, Handlers>;
172
174
  modules: Map<string | symbol, IRegistry[]>;
173
175
  createPort: (id: string) => Promise<ReturnType<IAdapterFactory>>;
176
+ getPort: (id: string) => ReturnType<IAdapterFactory> | undefined;
174
177
  replaceHandlers: (id: string, handlers: object) => Promise<void>;
175
178
  loadApi: (
176
179
  id: string,
@@ -219,6 +222,7 @@ export interface IApi {
219
222
  utLog: {
220
223
  createLog: ILog['logger'];
221
224
  };
225
+ attachCheckpoint?: (meta: IMeta) => void;
222
226
  handlers?: (api: {utError: IError; remote: IRemote; type: typeof Type}) => {
223
227
  extends?:
224
228
  | string
@@ -302,6 +306,22 @@ export interface IAdapter<T, C> {
302
306
  what: unknown,
303
307
  context: {requests: unknown; waiting: unknown; buffer: unknown},
304
308
  ) => void;
309
+ /**
310
+ * Optional lifecycle hook called when configuration changes.
311
+ * When present, the framework calls this instead of a full stop+start cycle.
312
+ * The adapter should inspect `diff` and only recreate the resources that
313
+ * actually changed (e.g. destroy and rebuild the DB connection pool when
314
+ * the `knex` sub-key is in the diff, but leave everything else intact).
315
+ *
316
+ * @param diff Flat map of dotted config paths to `{prev, next}` pairs
317
+ * @param next The full new effective config snapshot (via proxy)
318
+ * @param prev The full previous effective config snapshot
319
+ */
320
+ configChanged?: (
321
+ diff: Map<string, {prev: unknown; next: unknown}>,
322
+ next: object,
323
+ prev: object,
324
+ ) => Promise<void>;
305
325
  }
306
326
 
307
327
  export interface IAdapterFactory<T = Record<string, unknown>, C = Record<string, unknown>> {
@@ -381,6 +401,9 @@ export interface IMeta {
381
401
  };
382
402
  gateway?: object;
383
403
  validation?: unknown;
404
+ name?: string;
405
+ checkpoint?: CheckpointFn;
406
+ checkpoints?: Array<{name: string; data?: unknown; timestamp: number}>;
384
407
  }
385
408
 
386
409
  export type HRTime = [number, number];
@@ -519,14 +542,19 @@ export type ChainStep =
519
542
  ) => Promise<object>)
520
543
  | object;
521
544
 
545
+ export type CheckpointFn = (this: IMeta, name: string, data?: unknown) => void;
546
+
522
547
  export interface ILib {
523
548
  type: typeof Type;
524
549
  error: <T>(errors: T) => Record<keyof T, (params?: unknown, $meta?: IMeta) => ITypedError>;
525
550
  rename: <T extends object>(object: T, name: string) => T & {name: string};
551
+ /** @deprecated The framework now auto-names step arrays from handler names. */
526
552
  group: (name: string) => (handlers: ChainStep[]) => ChainStep[] & {name: string};
553
+ assert: typeof Assert | undefined;
527
554
  ulid: () => string;
528
555
  uuid4: () => string;
529
556
  uuid7: () => string;
557
+ setProperty: (obj: Record<string, unknown>, path: string, value: unknown) => void;
530
558
  merge<T, S1>(target: T, source: S1): T & S1;
531
559
  merge<T, S1, S2>(target: T, source1: S1, source2: S2): T & S1 & S2;
532
560
  merge<T, S1, S2, S3>(target: T, source1: S1, source2: S2, source3: S3): T & S1 & S2 & S3;