@adcops/autocore-varpick
v1.0.0
Published
Headless model behind autocore's variable pickers: catalog shape, search ranking, caret-aware insertion, and the ${fqdn} token grammar. No UI, no dependencies.
Readme
@adcops/autocore-varpick
The model behind autocore's variable pickers. Headless — no React, no widgets, no dependencies.
Why it exists
Every screen that asks an author to name a machine value used to be a bare text
box: a TIS field's source hinting gm.<variable_name>, a ${gm.…} bound, a
sequence expression over signals nobody published a description for. Nobody can
type a variable from a program they cannot see, and the names themselves are
often no help — pos is the ram position, but the file never says so.
Two packages fix that by rendering a picker, and they cannot share a line of UI:
| | widget layer |
|---|---|
| @adcops/autocore-react | PrimeReact today, @adcops/autocore-ui at 4.0 |
| @adcops/autocore-seq-react | plain HTML over design tokens, so one build renders on 3.5 and 4.0 |
What they must not differ on is what a variable is, how a search ranks, where
a pick lands in the text, and how a ${fqdn} token is spelled. That is this
package.
What's in it
model.ts—VariableEntry/CatalogGroup/Catalog. An entry carriesinsertseparately fromname, because the same variable ispress_position,gm.press_positionor${gm.press_position}depending on the field it lands in.search.ts— separator- and case-insensitive ranking. Descriptions are searched, so a variable is findable by what it means:"EL3356"findszforce_load.insert.ts— caret-aware insertion. An author who typedposand then opened the picker getspress_position, notpospress_position.token.ts— the${fqdn}grammar, in one place. It briefly lived in two TypeScript files and that is how the editor and the runtime came to disagree about what a bound was.gm.ts— turns agm.get_variablespayload into a catalog, grouped by ownership and filtered by whether a UI may write the variable.
Design rules
- No JSX here, ever. The moment this package renders anything it pins a consumer to one side of the 3.5 → 4.0 migration.
- A disabled entry is shown, greyed, with the reason. Hiding it answers "where is my variable?" with silence, which is the problem we started with.
- Never guess a unit or a label.
unitForcomes from the host's resolvedunits.json; absent means absent.
Publishing
This package must be published before either consumer can ship. Both declare
it as a normal semver dependency (^1.0.0), which is correct on publish and
unresolvable until it exists on the registry. Local development uses a symlink:
ln -s /path/to/autocore-varpick <consumer>/node_modules/@adcops/autocore-varpickIt must be published PUBLIC, explicitly
package.json carries "publishConfig": { "access": "public" }. Do not
remove it, and do not assume omitting publishConfig is the same thing.
A scoped package (@adcops/…) defaults to restricted on npm. Restricted
means a private package, private packages need a paid plan, and a free account
gets:
npm error code E402
npm error 402 Payment Required - You must sign up for private packagesThat is the same error @adcops/autocore-seq-react hits — but for the opposite
reason: it asks for restricted on purpose
(publishConfig.access: "restricted"), which is why it ships by git instead.
Here the access is public and the key is what makes it so.
@adcops/autocore-react has no publishConfig at all and publishes fine only
because its first publish set the access to public; npm remembers a
package's access level after that, so later publishes inherit it. A brand-new
scoped package has no such history, so the first publish is the one that has to
say public — either through the key above or npm publish --access public.
Development
npm test # builds, then runs tools/varpick.test.mjs against dist/The tests import the compiled output on purpose: both consumers import
dist, and a .ts-only test would not catch an export that never made it out
of the barrel.
