From 8a578720efec35da42bddc0aebbbdd3f42e75a5c Mon Sep 17 00:00:00 2001 From: ascottDI Date: Wed, 15 Jul 2026 14:45:11 +0100 Subject: [PATCH 1/4] Creating initial framework and first pass of development --- di/api/api.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ di/api/api.q | 67 +++++++++++++++++++++++++++++++++++++++++++ di/api/init.q | 4 +++ di/api/test.csv | 36 ++++++++++++++++++++++++ 4 files changed, 182 insertions(+) create mode 100644 di/api/api.md create mode 100644 di/api/api.q create mode 100644 di/api/init.q create mode 100644 di/api/test.csv diff --git a/di/api/api.md b/di/api/api.md new file mode 100644 index 00000000..3ccb23bc --- /dev/null +++ b/di/api/api.md @@ -0,0 +1,75 @@ +# di.api + +Registration and metadata for a process's public API functions. Each entry describes one callable +function — its name, whether it is public, and human-readable description / parameters / return +text. The registry is the single source of truth (there is no live-namespace scan, because module +code does not live in scannable root namespaces). + +**Registration model:** di.torq collects the api metadata from each module at startup and registers +it here centrally via `add`. di.api has no dependency on other modules, and other modules do not +depend on di.api. + +> **Status: v1 complete.** Registry (`add`/`getapi`) and query surface (`find`/`f`/`p`) are in +> place. The live-namespace-introspection tools from TorQ's `.api` (`search`, `whereami`, `mem`, +> `fullapi`'s namespace scan, `exportconfig`) are intentionally **not** ported — see "Not ported". + +## Initialisation & Dependencies + +`init` must be called before any other function. The `log` dependency is **required** — there is no +fallback, and the module does no adaptation. The `log` value must already be a binary +`` `info`warn`error!{[c;m]} `` dict (context symbol, message string), built from `di.log` or +hand-rolled; a raw monadic `kx.log` instance must be wrapped by the caller first. + +```q +api:use`di.api +logger:use`di.log +api.init[enlist[`log]!enlist `info`warn`error!(logger.info;logger.warn;logger.error)] +``` + +| Dependency | Key | Required | Description | +|---|---|---|---| +| logger | `` `log `` | yes | Functions `info`,`warn`,`error` — each binary `{[c;m] ...}` (context symbol, message string) | + +## Exported functions + +| Function | Signature | Description | +|---|---|---| +| `init` | `init[deps]` | Wire the injected logger and start with an empty registry. Errors immediately if the `log` dependency is missing or malformed. | +| `add` | `add[name;public;descrip;params;return]` | Register (or overwrite) one api entry. `name` is a symbol (the registry key), `public` a boolean; `descrip`/`params`/`return` are description text. Re-adding the same `name` updates it in place. | +| `getapi` | `getapi[]` | Return the full registry as a keyed table (keyed on `name`, columns `public`/`descrip`/`params`/`return`). | +| `find` | `find[s;p]` | Return registry entries whose name matches pattern `s` (a symbol — `` ` `` matches all, else a `*s*` substring — or a string glob) and whose `public` flag is in `p` (`1b` public-only, `01b` all). Case-insensitive; returns an unkeyed table. | +| `f` | `f[s]` | `find[s;01b]` — all matching entries, public and non-public. | +| `p` | `p[s]` | `find[s;1b]` — public matching entries only. | + +### Registry schema + +```q +([name:`u#`symbol$()] public:`boolean$(); descrip:(); params:(); return:()) +``` + +## Not ported from TorQ's `.api` (deliberate) + +TorQ's `.api` marries a registry with **live introspection of the root namespaces** (`\v`/`\f` scans, +grepping function definitions, sizing variables). That half does not fit the module world: module +code lives in each module's private `.z.m`, not in scannable root namespaces, so those tools would +see only a process's top-level glue, not the module logic they exist to inspect. Accordingly: + +| TorQ function | Why not ported | +|---|---| +| `u` | "public, excluding `.q`/`.Q`/`.h`/`.o`" — only filtered primitives out of the live scan; this registry holds only registered module functions, so `u` == `p`. | +| `search` / `s` | Greps live function *definitions* across root namespaces — cannot see module-private code. | +| `whereami` | Reverse-looks-up a function value to its name via the root scan — returns nothing for a function that lives inside a module (i.e. the usual error-trap case). | +| `fullapi` (namespace scan) | The scan-and-left-join-`detail` model does not apply; `getapi`/`find` serve the registry directly. | +| `mem` / `m` | Memory sizing belongs to `di.memstats`. | +| `exportconfig` / `exportallconfig` | Config lives in `di.config`'s resolved store, not scattered root variables — belongs with `di.config`/`di.torq`. | + +## Hard dependencies + +None. + +## Tests + +```q +k4unit:use`di.k4unit +k4unit.moduletest`di.api +``` diff --git a/di/api/api.q b/di/api/api.q new file mode 100644 index 00000000..2b755df8 --- /dev/null +++ b/di/api/api.q @@ -0,0 +1,67 @@ +/ api - registration and metadata for a process's public API functions +/ each entry describes one callable function: its name, whether it is public, and human-readable +/ description / parameters / return text. the registry is the single source of truth (there is no +/ live-namespace scan - module code is not in scannable root namespaces). +/ registration model: di.torq collects the api metadata from each module at startup and registers +/ it here centrally via add. di.api itself has no dependency on other modules. +/ (built up incrementally - step 1: registry + add + getapi) + +/ empty template for the registry (constant); .z.m.detail is the live, mutable copy +detailschema:([name:`u#`symbol$()] public:`boolean$(); descrip:(); params:(); return:()); + +init:{[deps] + / wire the injected logger (required, no fallback) and start with an empty registry. + / deps: a dict with a `log key holding a binary `info`warn`error dict of {[c;m]} loggers + / (from di.log or hand-rolled); no adaptation, so a monadic kx.log instance must be wrapped + / first. e.g. di.api.init[enlist[`log]!enlist logdep] + if[99h<>type deps; + '"di.api: deps must be a dict with a `log key"]; + if[not `log in key deps; + '"di.api: log dependency is required; pass `info`warn`error functions keyed on `log"]; + if[99h<>type deps`log; + '"di.api: log value must be a dict of `info`warn`error functions"]; + if[not all (`info`warn`error) in key deps`log; + '"di.api: log dict must have `info`warn`error keys; got: ",(", " sv string key deps`log)]; + .z.m.loginfo:deps[`log]`info; + .z.m.logwarn:deps[`log]`warn; + .z.m.logerr:deps[`log]`error; + .z.m.detail:detailschema; + }; + +add:{[name;public;descrip;params;return] + / register (or overwrite) one api entry describing a callable function. keyed on name, so + / re-adding the same name updates it in place. typically called by di.torq at startup for + / each module's exported functions. + if[not -11h=type name; + .z.m.logerr[`add;err:"di.api: name must be a symbol"]; + 'err; + ]; + if[not -1h=type public; + .z.m.logerr[`add;err:"di.api: public must be a boolean"]; + 'err; + ]; + .z.m.detail:.z.m.detail upsert (name;public;descrip;params;return); + }; + +getapi:{[] + / return the full registry of api entries as a keyed table (keyed on name) + :.z.m.detail; + }; + +find:{[s;p] + / return registry entries whose name matches pattern s and whose public flag is in p. + / s: a symbol (` matches everything, otherwise matched as a *s* substring) or a string glob. + / p: a boolean (or list) of public flags to include - 1b public-only, 01b all. + / name matching is case-insensitive. returns an (unkeyed) table of matching entries. + if[-11h=type s;s:$[null s;"*";"*",string[s],"*"]]; + if[not 10h=abs type s:s,(); + .z.m.logerr[`find;err:"di.api: search pattern must be a symbol or string"]; + 'err; + ]; + :select from getapi[] where (lower[string name] like lower s), public in p; + }; + +/ find all entries (public and non-public) +f:find[;01b]; +/ find public entries only +p:find[;1b]; diff --git a/di/api/init.q b/di/api/init.q new file mode 100644 index 00000000..4e445169 --- /dev/null +++ b/di/api/init.q @@ -0,0 +1,4 @@ +/ api module - registration and metadata for a process's public API functions +/ (scaffold - to be built up incrementally) +\l ::api.q +export:([init;add;getapi;find;f;p]) diff --git a/di/api/test.csv b/di/api/test.csv new file mode 100644 index 00000000..8cd17f2b --- /dev/null +++ b/di/api/test.csv @@ -0,0 +1,36 @@ +action,ms,bytes,lang,code,repeat,minver,comment +before,0,0,q,api:use`di.api,1,1,load the module +before,0,0,q,mylog:`info`warn`error!({[c;m]};{[c;m]};{[c;m]}),1,1,define a no-op binary logger {[c;m]} +before,0,0,q,api.init[enlist[`log]!enlist mylog],1,1,init with the required log dependency +comment,,,,,,,init - dependency validation +run,0,0,q,api.init[enlist[`log]!enlist mylog],1,1,init succeeds with a valid log dependency +fail,0,0,q,api.init[(::)],1,1,init rejects a non-dictionary deps +fail,0,0,q,api.init[enlist[`other]!enlist mylog],1,1,init rejects deps without a log key +fail,0,0,q,api.init[enlist[`log]!enlist 42],1,1,init rejects a non-dict log value +fail,0,0,q,api.init[enlist[`log]!enlist(`info`warn!({[c;m]};{[c;m]}))],1,1,init rejects a log dict missing the error key +comment,,,,,,,add and getapi - registry +run,0,0,q,api.init[enlist[`log]!enlist mylog],1,1,re-init to reset the registry to empty +true,0,0,q,0=count api.getapi[],1,1,registry starts empty after init +run,0,0,q,"api.add[`.gw.asyncexec;1b;""Execute async"";""[query;servers]"";""result""]",1,1,register a public api entry +true,0,0,q,1=count api.getapi[],1,1,add stores one entry +true,0,0,q,1b~(api.getapi[])[`.gw.asyncexec]`public,1,1,public flag stored +true,0,0,q,"""Execute async""~(api.getapi[])[`.gw.asyncexec]`descrip",1,1,description stored +run,0,0,q,"api.add[`.gw.asyncexec;0b;""updated"";""[]"";""x""]",1,1,re-add the same name +true,0,0,q,1=count api.getapi[],1,1,re-adding the same name overwrites (no duplicate) +true,0,0,q,0b~(api.getapi[])[`.gw.asyncexec]`public,1,1,re-add updates the entry in place +fail,0,0,q,"api.add[""notasym"";1b;""d"";""p"";""r""]",1,1,add rejects a non-symbol name +fail,0,0,q,api.add[`.x.f;1;`d;`p;`r],1,1,add rejects a non-boolean public flag +comment,,,,,,,find / f / p - query the registry +run,0,0,q,api.init[enlist[`log]!enlist mylog],1,1,re-init to reset the registry +run,0,0,q,"api.add[`.gw.asyncexec;1b;""a"";""p"";""r""]",1,1,seed a public entry +run,0,0,q,"api.add[`.gw.syncexec;1b;""a"";""p"";""r""]",1,1,seed another public entry +run,0,0,q,"api.add[`.api.add;1b;""a"";""p"";""r""]",1,1,seed a public entry with a different name +run,0,0,q,"api.add[`.internal.helper;0b;""a"";""p"";""r""]",1,1,seed a non-public entry +true,0,0,q,4=count api.f`,1,1,f with a null symbol returns all entries +true,0,0,q,3=count api.p`,1,1,p returns only the public entries +true,0,0,q,2=count api.f`exec,1,1,f matches names containing exec (substring) +true,0,0,q,2=count api.f`EXEC,1,1,name matching is case-insensitive +true,0,0,q,"2=count api.f""*gw*""",1,1,f accepts a string glob pattern +true,0,0,q,`.internal.helper in exec name from api.f`helper,1,1,f includes non-public entries +true,0,0,q,0=count api.p`helper,1,1,p excludes the non-public helper +fail,0,0,q,api.find[42;01b],1,1,find rejects a pattern that is not a symbol or string From 0177aac2ae407dea71217aa387ef15681d9f0e6d Mon Sep 17 00:00:00 2001 From: ascottDI Date: Thu, 16 Jul 2026 14:10:42 +0100 Subject: [PATCH 2/4] added functionality that each module will declare its own meta data on each API to get collected --- di/api/api.md | 2 +- di/api/api.q | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/di/api/api.md b/di/api/api.md index 3ccb23bc..70f0973c 100644 --- a/di/api/api.md +++ b/di/api/api.md @@ -61,7 +61,7 @@ see only a process's top-level glue, not the module logic they exist to inspect. | `whereami` | Reverse-looks-up a function value to its name via the root scan — returns nothing for a function that lives inside a module (i.e. the usual error-trap case). | | `fullapi` (namespace scan) | The scan-and-left-join-`detail` model does not apply; `getapi`/`find` serve the registry directly. | | `mem` / `m` | Memory sizing belongs to `di.memstats`. | -| `exportconfig` / `exportallconfig` | Config lives in `di.config`'s resolved store, not scattered root variables — belongs with `di.config`/`di.torq`. | +| `exportconfig` / `exportallconfig` / `torqnamespaces` | A faithful port needs config **values** (di.config `getmodule`) joined with **descriptions** (di.api `getapi`/`find`). di.config and di.api are both standalone and don't depend on each other, so the join belongs in **di.torq** (it has both). It is a **di.torq-era task**, not a di.config change: di.config's `getmodule` already returns per-namespace values; the missing piece is pairing them with the api descriptions across namespaces. | ## Hard dependencies diff --git a/di/api/api.q b/di/api/api.q index 2b755df8..8651d4ed 100644 --- a/di/api/api.q +++ b/di/api/api.q @@ -4,7 +4,7 @@ / live-namespace scan - module code is not in scannable root namespaces). / registration model: di.torq collects the api metadata from each module at startup and registers / it here centrally via add. di.api itself has no dependency on other modules. -/ (built up incrementally - step 1: registry + add + getapi) +/ public api: add (register an entry), getapi (whole registry), find/f/p (query by name + public). / empty template for the registry (constant); .z.m.detail is the live, mutable copy detailschema:([name:`u#`symbol$()] public:`boolean$(); descrip:(); params:(); return:()); @@ -58,7 +58,7 @@ find:{[s;p] .z.m.logerr[`find;err:"di.api: search pattern must be a symbol or string"]; 'err; ]; - :select from getapi[] where (lower[string name] like lower s), public in p; + :select from .z.m.detail where lower[string name] like lower s, public in p; }; / find all entries (public and non-public) From 955b4bb4068579b2739de78e83d868dafe862a1a Mon Sep 17 00:00:00 2001 From: ascottDI Date: Mon, 20 Jul 2026 09:27:36 +0100 Subject: [PATCH 3/4] added getapimeta so di.torq can collect and centrally register each modules meta data --- di/api/api.md | 1 + di/api/api.q | 70 +++++++++++++++++++++++++++++++++---------------- di/api/init.q | 2 +- di/api/test.csv | 5 ++++ 4 files changed, 55 insertions(+), 23 deletions(-) diff --git a/di/api/api.md b/di/api/api.md index 70f0973c..84e240e9 100644 --- a/di/api/api.md +++ b/di/api/api.md @@ -40,6 +40,7 @@ api.init[enlist[`log]!enlist `info`warn`error!(logger.info;logger.warn;logger.er | `find` | `find[s;p]` | Return registry entries whose name matches pattern `s` (a symbol — `` ` `` matches all, else a `*s*` substring — or a string glob) and whose `public` flag is in `p` (`1b` public-only, `01b` all). Case-insensitive; returns an unkeyed table. | | `f` | `f[s]` | `find[s;01b]` — all matching entries, public and non-public. | | `p` | `p[s]` | `find[s;1b]` — public matching entries only. | +| `getapimeta` | `getapimeta[]` | Return **this module's own** api metadata — one `(name;public;descrip;params;return)` row per exported function — for di.torq to collect and register. Every module exposes this (the module-owned metadata convention). Names are bare (the module's own); di.torq applies process-wide qualification when registering. | ### Registry schema diff --git a/di/api/api.q b/di/api/api.q index 8651d4ed..7beed0ac 100644 --- a/di/api/api.q +++ b/di/api/api.q @@ -1,19 +1,15 @@ -/ api - registration and metadata for a process's public API functions -/ each entry describes one callable function: its name, whether it is public, and human-readable -/ description / parameters / return text. the registry is the single source of truth (there is no -/ live-namespace scan - module code is not in scannable root namespaces). -/ registration model: di.torq collects the api metadata from each module at startup and registers -/ it here centrally via add. di.api itself has no dependency on other modules. -/ public api: add (register an entry), getapi (whole registry), find/f/p (query by name + public). +/ api - a registry of a process's callable functions: one entry per function holding its name, +/ public flag, and description / params / return text. registry-only (no live namespace scan - +/ module code is not in root namespaces). di.torq registers each module's metadata here via add; +/ di.api depends on no other module. public api: add, getapi, find/f/p. -/ empty template for the registry (constant); .z.m.detail is the live, mutable copy +/ registry template (constant); .z.m.detail is the live copy detailschema:([name:`u#`symbol$()] public:`boolean$(); descrip:(); params:(); return:()); init:{[deps] - / wire the injected logger (required, no fallback) and start with an empty registry. - / deps: a dict with a `log key holding a binary `info`warn`error dict of {[c;m]} loggers - / (from di.log or hand-rolled); no adaptation, so a monadic kx.log instance must be wrapped - / first. e.g. di.api.init[enlist[`log]!enlist logdep] + / wire the injected logger (required, no fallback) and start with an empty registry. deps: a `log + / key holding a binary `info`warn`error dict of {[c;m]} loggers (di.log or hand-rolled; a monadic + / kx.log instance must be wrapped first). e.g. di.api.init[enlist[`log]!enlist logdep] if[99h<>type deps; '"di.api: deps must be a dict with a `log key"]; if[not `log in key deps; @@ -29,9 +25,8 @@ init:{[deps] }; add:{[name;public;descrip;params;return] - / register (or overwrite) one api entry describing a callable function. keyed on name, so - / re-adding the same name updates it in place. typically called by di.torq at startup for - / each module's exported functions. + / register (or overwrite) one entry, keyed on name (re-adding a name updates in place). + / called by di.torq at startup for each module's exported functions. if[not -11h=type name; .z.m.logerr[`add;err:"di.api: name must be a symbol"]; 'err; @@ -44,15 +39,14 @@ add:{[name;public;descrip;params;return] }; getapi:{[] - / return the full registry of api entries as a keyed table (keyed on name) + / return the whole registry (keyed table, keyed on name) :.z.m.detail; }; find:{[s;p] - / return registry entries whose name matches pattern s and whose public flag is in p. - / s: a symbol (` matches everything, otherwise matched as a *s* substring) or a string glob. - / p: a boolean (or list) of public flags to include - 1b public-only, 01b all. - / name matching is case-insensitive. returns an (unkeyed) table of matching entries. + / registry entries whose name matches s and whose public flag is in p. s: a symbol (` = all, else + / a *s* substring) or a string glob; p: public flags to include (1b public-only, 01b all). + / case-insensitive; returns an unkeyed table. if[-11h=type s;s:$[null s;"*";"*",string[s],"*"]]; if[not 10h=abs type s:s,(); .z.m.logerr[`find;err:"di.api: search pattern must be a symbol or string"]; @@ -61,7 +55,39 @@ find:{[s;p] :select from .z.m.detail where lower[string name] like lower s, public in p; }; -/ find all entries (public and non-public) +/ all entries (public and non-public) f:find[;01b]; -/ find public entries only +/ public entries only p:find[;1b]; + +getapimeta:{[] + / this module's api metadata, one row per exported function, for di.torq to collect and register + / with di.api. names are bare (the module's own); di.torq applies the process-wide qualification. + :([] + name:`init`add`getapi`find`f`p`getapimeta; + public:0011110b; + descrip:( + "wire the injected logger and start an empty registry"; + "register (or overwrite) one api entry, keyed on name"; + "return the whole registry (keyed table)"; + "registry entries matching a name pattern and public flag"; + "find[;01b] - all entries matching a name pattern"; + "find[;1b] - public entries matching a name pattern"; + "this module's api metadata rows"); + params:( + "[dict: deps with a `log key]"; + "[symbol: name; boolean: public; descrip; params; return]"; + "[]"; + "[symbol|string: name pattern; boolean(list): public flags]"; + "[symbol|string: name pattern]"; + "[symbol|string: name pattern]"; + "[]"); + return:( + "null"; + "null"; + "keyed table: the registry"; + "table: matching entries"; + "table: matching entries"; + "table: matching public entries"; + "table: metadata rows")); + }; diff --git a/di/api/init.q b/di/api/init.q index 4e445169..e7d0887d 100644 --- a/di/api/init.q +++ b/di/api/init.q @@ -1,4 +1,4 @@ / api module - registration and metadata for a process's public API functions / (scaffold - to be built up incrementally) \l ::api.q -export:([init;add;getapi;find;f;p]) +export:([init;add;getapi;find;f;p;getapimeta]) diff --git a/di/api/test.csv b/di/api/test.csv index 8cd17f2b..78808331 100644 --- a/di/api/test.csv +++ b/di/api/test.csv @@ -34,3 +34,8 @@ true,0,0,q,"2=count api.f""*gw*""",1,1,f accepts a string glob pattern true,0,0,q,`.internal.helper in exec name from api.f`helper,1,1,f includes non-public entries true,0,0,q,0=count api.p`helper,1,1,p excludes the non-public helper fail,0,0,q,api.find[42;01b],1,1,find rejects a pattern that is not a symbol or string +comment,,,,,,,getapimeta - module api metadata +true,0,0,q,(asc key api)~asc exec name from api.getapimeta[],1,1,getapimeta documents exactly the module's exports +true,0,0,q,`name`public`descrip`params`return~cols api.getapimeta[],1,1,getapimeta rows carry the registry columns +true,0,0,q,1b~(1!api.getapimeta[])[`find]`public,1,1,a discovery function (find) is marked public +true,0,0,q,0b~(1!api.getapimeta[])[`init]`public,1,1,framework plumbing (init) is not public From bf376aabe3d746b559fba3affab649a8f9e132c4 Mon Sep 17 00:00:00 2001 From: ascottDI Date: Mon, 20 Jul 2026 16:37:41 +0100 Subject: [PATCH 4/4] simplified the getapi data framework to make it less intrusive and bulky inside other processes --- di/api/api.md | 23 +++++++++++++++++++++++ di/api/api.q | 36 +++++++++--------------------------- di/api/init.q | 4 ++-- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/di/api/api.md b/di/api/api.md index 84e240e9..f58a1c5f 100644 --- a/di/api/api.md +++ b/di/api/api.md @@ -48,6 +48,29 @@ api.init[enlist[`log]!enlist `info`warn`error!(logger.info;logger.warn;logger.er ([name:`u#`symbol$()] public:`boolean$(); descrip:(); params:(); return:()) ``` +## Design decisions + +- **Registry-only, no live scan.** The core departure from TorQ. Module functions live in private + `.z.m`, invisible to `\v`/`\f`, so a live-namespace scan would report a process's top-level glue as + its API, not the module logic. The registry is populated explicitly instead and is the single + source of truth (see "Not ported" for the TorQ functions this drops). +- **Module-owned metadata (`getapimeta`).** Rather than a central hand-maintained list, each module + declares its own API as data — one `(name;public;descrip;params;return)` row per export — and + `di.torq` collects and registers them via `add`. Names in `getapimeta` are **bare** (the module's + own); `di.torq` applies process-wide qualification. `di.api` dog-foods this: `getapimeta` documents + its own seven exports, and a test asserts every `export` name has a matching row. +- **Metadata is a compact row literal, not resident data.** `getapimeta` is built with the + row-oriented `flip cols!flip(rows)` idiom — one self-contained line per function — rather than five + parallel column-lists, so it stays terse and a function can't drift out of column alignment. It + costs the module nothing at runtime: it's a *function*, materialised once when `di.torq` calls it + at startup, then registered centrally; the module keeps no resident copy. This is the form the + modularisation skill mandates for every module. +- **`find` unifies the query surface.** `f` and `p` are just projections `find[;01b]` / `find[;1b]`, + so there is one matching implementation. Symbol patterns become `*substring*`, `` ` `` matches all, + and strings pass through as globs — all case-insensitive. +- **Minimal, registered surface.** The public API is small and every entry is something `di.torq` + will actually register. TorQ's introspection helpers are dropped, not stubbed (below). + ## Not ported from TorQ's `.api` (deliberate) TorQ's `.api` marries a registry with **live introspection of the root namespaces** (`\v`/`\f` scans, diff --git a/di/api/api.q b/di/api/api.q index 7beed0ac..8e156518 100644 --- a/di/api/api.q +++ b/di/api/api.q @@ -63,31 +63,13 @@ p:find[;1b]; getapimeta:{[] / this module's api metadata, one row per exported function, for di.torq to collect and register / with di.api. names are bare (the module's own); di.torq applies the process-wide qualification. - :([] - name:`init`add`getapi`find`f`p`getapimeta; - public:0011110b; - descrip:( - "wire the injected logger and start an empty registry"; - "register (or overwrite) one api entry, keyed on name"; - "return the whole registry (keyed table)"; - "registry entries matching a name pattern and public flag"; - "find[;01b] - all entries matching a name pattern"; - "find[;1b] - public entries matching a name pattern"; - "this module's api metadata rows"); - params:( - "[dict: deps with a `log key]"; - "[symbol: name; boolean: public; descrip; params; return]"; - "[]"; - "[symbol|string: name pattern; boolean(list): public flags]"; - "[symbol|string: name pattern]"; - "[symbol|string: name pattern]"; - "[]"); - return:( - "null"; - "null"; - "keyed table: the registry"; - "table: matching entries"; - "table: matching entries"; - "table: matching public entries"; - "table: metadata rows")); + / one self-contained (name;public;descrip;params;return) row per line - flip cols!flip rows. + :flip `name`public`descrip`params`return!flip( + (`init; 0b; "wire the injected logger and start an empty registry"; "[dict: deps with a `log key]"; "null"); + (`add; 0b; "register (or overwrite) one api entry, keyed on name"; "[symbol: name; boolean: public; descrip; params; return]"; "null"); + (`getapi; 1b; "return the whole registry (keyed table)"; "[]"; "keyed table: the registry"); + (`find; 1b; "registry entries matching a name pattern and public flag"; "[symbol|string: name pattern; boolean(list): public flags]"; "table: matching entries"); + (`f; 1b; "find[;01b] - all entries matching a name pattern"; "[symbol|string: name pattern]"; "table: matching entries"); + (`p; 1b; "find[;1b] - public entries matching a name pattern"; "[symbol|string: name pattern]"; "table: matching public entries"); + (`getapimeta; 0b; "this module's api metadata rows"; "[]"; "table: metadata rows")); }; diff --git a/di/api/init.q b/di/api/init.q index e7d0887d..ab0ab10c 100644 --- a/di/api/init.q +++ b/di/api/init.q @@ -1,4 +1,4 @@ -/ api module - registration and metadata for a process's public API functions -/ (scaffold - to be built up incrementally) +/ api module - registration and metadata for a process's public API functions. +/ registry-only (no live namespace scan); di.torq collects each module's getapimeta and registers here. \l ::api.q export:([init;add;getapi;find;f;p;getapimeta])