Skip to content

docs(build): document the browser build produced by streamConfig.mockWeb - #31

Merged
allanbowe merged 5 commits into
masterfrom
docs/browser-build
Oct 25, 2026
Merged

allanbowe merged 5 commits into
masterfrom
docs/browser-build

Conversation

@sasjs-dev

@sasjs-dev sasjs-dev Bot commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

What

Documents the browser build that sasjs build produces when streamConfig.mockWeb is true (#287 in sasjs/utils, #1492 in sasjs/cli).

  • what the artefact is, and that mockWeb is independent of streamWeb (the same target still deploys for real)
  • the requirements: JavaScript services, webSourcePath pointing at the built frontend, and an appLoc that matches the one the app was built with
  • where the site is written (mockWebFolder, sasjsbuild/mock by default) and that the virtual drive is seeded from the build output
  • how the request flow works, and that state persists in IndexedDB across a refresh
  • how to serve it, including why file:// does not work
  • the limits, stated plainly: single user, no authentication, no SAS engine

Why

Two reasons. The page had no mention of the feature at all, and the generated reference page at cli.sasjs.io/sasjsconfig.html is built from a $ref to sasjs/utils main, so it renders whatever that schema happened to be at the last push to master - which is why it still advertises the old streamWebFolder default and has no mockWeb. A push to master regenerates it; this PR is that push, and the prose is the part that has to be written by hand.

Verified locally with the same generator the workflow uses: the rebuilt page exposes #streamConfig_mockWeb and #streamConfig_mockWebFolder, and both links in this page resolve.

sasjs added 2 commits October 24, 2026 13:13
sasjs build emits a self-contained static site when mockWeb is set: same services, same webout contract, no server and no SAS. The page covers the required shape of the target, where the site lands (mockWebFolder, sasjsbuild/mock by default), how the request flow works, and how to serve it - a service worker needs a secure context, so localhost and https work and file:// does not. It also states the limits plainly: single user, no authentication, and no SAS engine, so SAS-backed services cannot run in it.
Covers what a snapshot is, how to capture one (window.SASjsMock.download()), where to put the file, how to reset or ship the plain seed instead, and the trap that state tied to an origin - a licence, for instance - does not decrypt anywhere else, which is why a snapshot has to be captured on the domain it is deployed to. Also notes that the host assets carry a ?v= hash, so index.html and sw.js have to be uploaded with the rest.

@sasjs-dev sasjs-dev Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full diff at ff6ed4a (docs/build.md, 72 added lines). The document was cross-checked against the implementation it describes - sasjs/cli #1492 at its current head eb9a011a (mockSite.ts, persist.js, sw.js) - and against the sasjsconfig schema at @sasjs/utils 4.1.0: the mockWeb/mockWebFolder/webSourcePath anchors the page links to all exist in that schema with matching $ids, the default mockWebFolder (sasjsbuild/mock) and the snapshot flow (build-folder mock-snapshot.json copied to host/vfs-snapshot.json, preferred over the seed, reported as "snapshot": true in host/mock-config.json, window.SASjsMock.download()/reset()) all match the code, and the secure-context warning for service workers is correct. No semantic-release or releaserc exists in this repo, so the conventional-commit release rule does not apply; the two commit subjects are conventional regardless.

  • docs/build.md:53-59 and the whole section - the page documents the mockWeb feature as it ships in sasjs/cli #1492, which is still open and whose head has moved twice in the last hour (9bc1e96 -> eb9a011a, with the runtime and builder rewritten in the push: the flags the docs never mention are gone, the output-folder guard is new, binary files are now skipped rather than shipped as mojibake). Merge this only with (or after) the CLI PR so the docs and the code land together - a merge now documents a build that will not exist until #1492 merges, and the cross-repo links (cli.sasjs.io/sasjsconfig.html#streamConfig_mockWeb) resolve only after the next master publish regenerates sasjsconfig.html from the utils schema. If the CLI PR changes shape again before merge, re-check the snapshot section in particular - the "no app-specific knowledge" and snapshot-capture workflows are the parts most sensitive to the runtime's boot path.

  • repo root (no .pre-commit-config.yaml) - the repo carries no gitleaks pre-commit hook: .git-hooks/ holds only a commit-msg Conventional Commits check, and package.json's postinstall points git at .git-hooks only when the one-time install was run by hand. A docs repo still takes paste-style secrets in prose and code blocks. Add .pre-commit-config.yaml with the gitleaks hook pinned to an exact release tag (v8.30.1 current).

2 findings above for review.

A mock of a streaming service was the one thing a browser build could not do:
the download headers were ignored and a byte body had nowhere to go. Say how a
service declares a file response, in text and in bytes, and what the host does
with the headers it was given.

Pairs with sasjs/cli#1494.
@sasjs-dev

sasjs-dev Bot commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

Added a third commit: Downloads and file responses.

It documents the browser counterpart of %mp_streamfile, which this page described as a general capability but not as a way to return a file:

  • declaring Content-type / Content-Disposition in _SASJS_WEBOUT_HEADERS, with a text example (CSV) and a byte example (zip via Buffer.from / Uint8Array)
  • that only those two headers are applied, and why (no cache and no cookies on a static host)
  • that _debug returns the text frame instead
  • the two limits: bytes are stored base64 in the drive, and an undeclared type falls back to application/octet-stream

It pairs with sasjs/cli#1494, which makes this behaviour real: until that lands a browser build ignores the headers and cannot carry a byte body. Merge order therefore wants #1494 first (or the same release), otherwise this page describes a capability a reader does not have yet.

@sasjs-dev sasjs-dev Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review at ae66c68 - scope is the delta from the ff6ed4a review: the single docs commit adding the "Downloads and file responses" section to docs/build.md. That section was checked against the implementation it describes - sasjs/cli #1494 at its current head b57bbb7 - by running the described shapes against the runtime: the text form (assign _webout, declare headers), the byte form (Buffer.from(bytes) and Buffer.from(base64, 'base64') to weboutPath, both arriving as a binary body), the content-type/content-disposition-only header policy, the application/octet-stream fallback, and the _debug text frame all behave as documented. The "reads back as bytes" claim matches readFileSync returning a Buffer for byte-written files. The section's claims are accurate; no corrections needed in the delta itself. No semantic-release/releaserc in this repo, so the conventional-commit release rule does not apply; the commit subjects are conventional regardless. CI note: publish.yml runs only on master pushes, so PRs carry no pipeline to gate on.

  • docs/build.md (Downloads and file responses) - the section documents the downloads feature of sasjs/cli #1494, which is still open: the base mockWeb build is now in cli main (merged as #1492), but the header/binary webout behaviour this section describes ships only when #1494 merges. The ff6ed4a finding's shape is unchanged - merge this with (or after) #1494 so the docs and the code land together; if #1494 changes shape before merge, re-check the Buffer.from argument list and the octet-stream fallback lines first, as those are the claims pinned to its implementation.

  • repo root (no .pre-commit-config.yaml) - unchanged from the ff6ed4a review: the repo carries no gitleaks pre-commit hook (.git-hooks/ holds only a commit-msg Conventional Commits check, and package.json's postinstall points git at .git-hooks only when the one-time install was run by hand). A docs repo still takes paste-style secrets in prose and code blocks. Add .pre-commit-config.yaml with the gitleaks hook pinned to an exact release tag (v8.30.1 current).

2 findings above for review.

@sasjs-dev sasjs-dev Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the docs/build.md addition against the code it documents (sasjs/cli#1494). Accurate on the two applied headers, the application/octet-stream default, the _debug text frame, the byte-body storage caveat and the RFC 6266 filename guidance - all match sw.js and runtime-core.js. Docs-only, so no hardening checklist applies.

  • docs/build.md:109 - "Two things to keep in mind:" introduces three bullets (base64 storage, octet-stream default, RFC 6266 filenames). Change the lead-in to three, or fold one bullet in.

No blocking issues.

@allanbowe
allanbowe merged commit 11ca595 into master Oct 25, 2026
@allanbowe
allanbowe deleted the docs/browser-build branch October 25, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant