@bluestep-systems/bspecs 0.13.0 → 0.14.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bluestep-systems/bspecs",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Spec-driven BlueStep development with AI agents — scaffolder and project conventions for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,6 +11,7 @@ Entries read: `path — what it covers. Load when <trigger>.` Match the trigger
11
11
  ## reference/ — single-topic platform and API detail
12
12
 
13
13
  - [reference/api-patterns.md](reference/api-patterns.md) — B API usage: Java optionals (`.opt()/.orElse()`), field types and access, `mergeTag()` L/F/I/H codes, multi-entry-form (MEF) entries, query access, Java collections, writing date/datetime fields, `B.commit()` and formula triggers, endpoint request/response, base64, user/session. Load when calling the `B` API, reading or writing fields, or wiring an endpoint's request/response.
14
+ - [reference/b-include-element.md](reference/b-include-element.md) — `<b-include>` browser custom element that fetches HTML from a URL and renders it inline (client-side `<jsp:include>`/SSI); `src`/`run-scripts`/`csrf` attrs, spinner/error behavior, trusted-template-only (neutralized in user HTML). Load when injecting a dynamic async HTML fragment in the browser.
14
15
  - [reference/blueiq-credit-integration-playbook.md](reference/blueiq-credit-integration-playbook.md) — step-by-step playbook for wiring a new OpenAI/AI feature into the BlueIQ credit gate and ledger. Load when adding an AI feature that must consume BlueIQ credits.
15
16
  - [reference/chronounit-months.md](reference/chronounit-months.md) — `ChronoUnit.MONTHS.between` counts elapsed (day-aware) months, not calendar-month boundaries. Load when computing a month difference or porting SQL `DATEDIFF(MONTH)`.
16
17
  - [reference/code-patterns.md](reference/code-patterns.md) — working BsJs skeletons: queries, MergeReport server/client bridge, endpoints, error handling, performance (per-row queue, lazy init), component import, debugging. Load when starting a query, MergeReport, or endpoint and you want a known-good pattern.
@@ -31,6 +32,7 @@ Entries read: `path — what it covers. Load when <trigger>.` Match the trigger
31
32
  - [reference/id-full-vs-short.md](reference/id-full-vs-short.md) — `Id.toString()` is the full `ClassID___ShortID`; `shortId()` is just the trailing number; `optById` needs the full form. Load when round-tripping an entry id or calling `optById`.
32
33
  - [reference/internal-loopback-fetch.md](reference/internal-loopback-fetch.md) — endpoint-to-endpoint loopback within an org uses `B.net.fetch` on a relative path with `credentials:true`, not the external `httpRequester`. Load when one endpoint calls another in the same org.
33
34
  - [reference/localdate-parse.md](reference/localdate-parse.md) — `Java.Time.LocalDate` is a TypeScript namespace only; use `B.time.LocalDate` for runtime `parse()`/`now()`. Load when parsing or creating a LocalDate.
35
+ - [reference/merge-report-async-loading.md](reference/merge-report-async-loading.md) — the "Asynchronous Loading" option on a Data Merge Report lazy-loads it AFTER the page resolves (BSJS used an `async` metadata property, not the checkbox); parent→child fan-out, the obsolete `formFooter` hack, and the script-timing gotcha. Load when a merge report is slow or should lazy-load, or page script depends on async merge content.
34
36
  - [reference/merge-report-memo-json.md](reference/merge-report-memo-json.md) — the "MergeReport + memo field JSON" framework: embed a custom interactive widget on a form that persists its state as JSON in a hidden memo field. Load when building a stateful custom widget on a form.
35
37
  - [reference/merge-report-static-index.md](reference/merge-report-static-index.md) — with a `static/` bundle, `static/index.html` is the page and `app.ts` `B.out` is NOT injected; put the mount + config island in `index.html` and run the client on `DOMContentLoaded`. Load when a MergeReport has a `static/` bundle.
36
38
  - [reference/merge-report-urls.md](reference/merge-report-urls.md) — BSJS equivalents of relatescript `lookupMergeReport`/`lookupMergeReportScript`, and how to get `viewUrl`/`printUrl`. Load when looking up a MergeReport URL in code.
@@ -0,0 +1,46 @@
1
+ ---
2
+ description: "`<b-include>` is a browser custom element that fetches HTML from a URL and renders it inline — client-side `<jsp:include>`/SSI for dynamic async content; trusted-template only (neutralized in user-supplied HTML)"
3
+ ---
4
+
5
+ `<b-include>` is a **browser custom element** (defined in `dom.ts:432-560`) that
6
+ **fetches HTML from a URL and renders it inline** — think client-side `<jsp:include>`
7
+ / server-side-include for the browser. Use it for dynamic, async page fragments.
8
+
9
+ **Syntax** — must use an explicit closing tag (it is **not** self-closing):
10
+ ```html
11
+ <b-include src="/path/to/fragment.jsp"></b-include>
12
+ ```
13
+
14
+ **Attributes**
15
+
16
+ | Attribute | Values | Purpose |
17
+ | ------------- | --------------------- | ------- |
18
+ | `src` | URL | Content to fetch. **Reactive** — changing it re-fetches automatically. |
19
+ | `run-scripts` | `"true"` \| (omit) | When `"true"`, `<script>` tags in the fetched HTML are re-inserted so the browser executes them. Default: scripts are inert. |
20
+ | `csrf` | `"true"` \| `"false"` \| (omit) | Force CSRF handling. Omit for auto-detect: same-origin → `csrf.fetch`, cross-origin → plain fetch. |
21
+
22
+ **Examples**
23
+ ```html
24
+ <!-- Basic same-origin include (CSRF token auto-attached) -->
25
+ <b-include src="/shared/content/fragment.jsp"></b-include>
26
+
27
+ <!-- Include a fragment and run its <script> tags -->
28
+ <b-include src="/path/with/scripts.html" run-scripts="true"></b-include>
29
+
30
+ <!-- Cross-origin with forced CSRF off (remote must send CORS headers) -->
31
+ <b-include src="https://other.example.com/widget" csrf="false"></b-include>
32
+ ```
33
+
34
+ **Behavior**
35
+ - Shows a spinner while loading; shows an error box with a **"Reload"** link on failure.
36
+ - Re-setting `src` aborts the in-flight request and re-fetches.
37
+ - Removal from the DOM aborts any pending request.
38
+ - Drivable from JS via properties: `el.src`, `el.runScripts`, `el.csrf`.
39
+
40
+ **Security — trusted templates only.** `<b-include>` is **neutralized in user-supplied
41
+ content** by `HTMLFilter.java:46` (rewritten to `<xxb-includexx>`) to prevent injection.
42
+ Only use it in **trusted templates**, never in user-editable HTML. The Zesty editor
43
+ whitelists it as `b-include[src|run-scripts|csrf]` (`zesty3.ts:130`).
44
+
45
+ For the server-side config alternative (a merge report that lazy-loads after the page),
46
+ see [merge-report-async-loading](merge-report-async-loading.md).
@@ -0,0 +1,41 @@
1
+ ---
2
+ description: A Data Merge Report's "Asynchronous Loading" option makes it lazy-load AFTER the rest of the page resolves instead of as part of the initial request; in BSJS this was an `async` metadata property rather than the checkbox
3
+ ---
4
+
5
+ A BlueStep **Data Merge Report** has an **"Asynchronous Loading"** checkbox under
6
+ *Advanced Usage Options* (Step 3 of the merge-report edit wizard). Turning it on
7
+ makes the merge report **resolve in a lazy-load rather than as part of the initial
8
+ page request** — the rest of the page renders first, then the merge report loads
9
+ in separately so a heavy merge doesn't slow everything else down.
10
+
11
+ This is **not a new feature**. It maps directly to the underlying DB object and has
12
+ existed for a long time. **BSJS had no toggle** — you set an `async` property in the
13
+ component metadata, which inserted a layer of indirection over that same DB object.
14
+ Removing that BSJS layer is what surfaced the plain checkbox; it only *looks* new to
15
+ anyone who previously only used BSJS.
16
+
17
+ **Parent → child behavior.** When a merge report calls another async merge report,
18
+ the **parent's HTML resolves first**, the page loads, and then each async child
19
+ loads separately — so a parent merge report that fans out to N children can give
20
+ each child its own independent loader. (The resident-med report does exactly this:
21
+ a nasty merge that renders per resident, switched to async, **loads in batches of
22
+ 3 at a time**.)
23
+
24
+ **Good use cases:** heavy/slow merges; merge reports embedded on a form; a parent
25
+ merge report aggregating several child merge reports; query-driven layouts where
26
+ displayed merge-report fields can stream in after the header data.
27
+
28
+ **Gotcha — script timing.** Because the content is no longer present at initial page
29
+ load, any page script that **expects the async merge report's DOM/data to already be
30
+ there will break**. If you have client code depending on the merge report, gate it on
31
+ the async content actually arriving rather than on initial `DOMContentLoaded`.
32
+
33
+ **Obsolete hack.** Older setups added a marker like
34
+ `htmlCode += '<span id="formFooter"></span>'` to force the async merge report to load
35
+ properly. With the current setup this should **no longer be necessary** — don't carry
36
+ it forward into new code.
37
+
38
+ For dynamic async content driven from the client (rather than this server-side
39
+ config), see [b-include element](b-include-element.md). Related merge-report detail:
40
+ [merge-report-static-index](merge-report-static-index.md),
41
+ [merge-report-memo-json](merge-report-memo-json.md).