@ham2k/extension-sdk 0.5.7 → 0.7.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/docs/templates.md CHANGED
@@ -48,6 +48,7 @@ is `{{ op.refs | refLabels | sentence }}`.
48
48
  | `qso` | when the placement's triggers ask for it | — | ✓ | the draft contact, as far as it is typed |
49
49
  | `config` | ✓ | — | — | — |
50
50
  | `log` | — | ✓ | ✓ | — |
51
+ | `keyer` | — | — | — | ✓ (and the keyer area's labels) |
51
52
 
52
53
  A namespace a surface has nothing for is **absent**, not blank — which is
53
54
  what makes `{% if qso %}` an honest question. Registered exports get the operation plus the selected file’s `log` values.
@@ -75,13 +76,46 @@ printing `{{ op.startTime }}–{{ op.endTime }}` understates the session by
75
76
  that contact's length.
76
77
 
77
78
  ### `qso` — one contact
78
- `call`, `their`, `our` (both whole, so `qso.their.guess.name` reaches the
79
+ `call`, `fullCall`, `partial`, `nextCall`, `nextPartial`, `state`, `name`, `their`, `our` (both whole, so `qso.their.guess.name` reaches the
79
80
  lookup's answer), `band`, `mode`, `freq`, `rstSent`, `rstRcvd`, `serialSent`,
80
81
  `serialRcvd`, `notes`, `date`, `dateCompact`, `time`, `at`, `startAtMillis`,
81
82
  `refs` — and two short forms for the sent side, `rst` (= `rstSent`) and
82
83
  `serial` (= `serialSent`), since a CW message is what we send and that is
83
84
  where these get typed: `{{ qso.call }} {{ qso.rst | cut }} {{ qso.serial | pad: 3 | cut }}`.
84
85
 
86
+ In a draft, `call` is ONE call, read at the cursor as the call-info line
87
+ reads it — not the field as typed, which may hold a `//` stack or a comma
88
+ list ([logging-fields.md](https://github.com/ham2k/halo/blob/main/docs/design/logging-fields.md)). On a stack it is
89
+ the call Enter logs, or — when there is none — the partial under the
90
+ cursor, or the nearest one beside it when the cursor sits in an empty
91
+ segment a just-typed `//` opened; in
92
+ a comma list, where Enter logs every call, it is the one the cursor is on.
93
+ `their.call` stays the field as typed. On a stack, two more name the rest of
94
+ it: `nextCall`, the call the Enter after this one would log, and
95
+ `nextPartial`, the last entry left in the field once this one logs —
96
+ usually the call still being copied. With `KN2//KI2D//NK2Y//FR` and the
97
+ cursor at the end, that is `NK2Y`, `KI2D` and `FR`; with the cursor on
98
+ `KI2D`, it is `KI2D`, `NK2Y` and `FR`. Both are empty outside a stack and on
99
+ a logged contact.
100
+
101
+ `call` may be a partial still being copied, which is right for asking it
102
+ back (`{{ qso.call }}?`) and wrong for answering it. `fullCall` is `call`
103
+ when it reads as a callsign and blank otherwise; `partial` is the reverse.
104
+ Exactly one of them is `call`, so a message can branch on which:
105
+ `{% if qso.fullCall != blank %}…{% elsif qso.partial != blank %}{{ qso.partial }}?{% endif %}`.
106
+ A logged contact's call is always a `fullCall`.
107
+
108
+ `state` and `name` are what was typed, else what the lookup found
109
+ (`their.state` or `their.guess.state`, likewise for the name) — and `name`
110
+ is only the first word, since `GM {{ qso.name }}` is a greeting, not a
111
+ directory entry. Reach the whole name through `qso.their.name` /
112
+ `qso.their.guess.name`.
113
+
114
+ Enter Sends Messages renders its thanks AFTER the contact logs, against the
115
+ entry the log left ([logging-fields.md](https://github.com/ham2k/halo/blob/main/docs/design/logging-fields.md) § Enter
116
+ Sends Messages) — so in a thanks keyed by ESM, `qso.call`, `qso.name` and
117
+ the rest name the NEXT station, or nothing, never the one just logged.
118
+
85
119
  `rstSent` is what WE sent — QSON stores each side's report under its own
86
120
  `sent`, and these are named for the operator's view of the contact.
87
121
 
@@ -100,6 +134,22 @@ Whatever that panel's `form` declared, under the keys it used.
100
134
  `handlerShortName`, `format`, `exportType`, `modifier`, `extension`,
101
135
  `compact`.
102
136
 
137
+ ### `keyer` — the CW messages
138
+ `msg1` … `msg8`: the active set's messages, each RENDERED against the same
139
+ context, so one message can include another —
140
+ `TU {{ keyer.msg1 }}` thanks the station and calls CQ again with whatever F1
141
+ holds. A message is expanded only where a template names it, so a branch
142
+ not taken costs nothing — which is what lets ESM's thanks answer the next
143
+ stacked caller or ask a partial back, and send nothing more when there is
144
+ neither:
145
+ `TU {% if qso.fullCall != blank %}{{ keyer.msg5 }} {{ keyer.msg2 }}{% elsif qso.partial != blank %}{{ qso.partial }}?{% endif %}`.
146
+
147
+ A message that reaches itself — directly, or through others — is an error
148
+ naming the loop (`a message includes itself: F3 → F1 → F3`), and like any
149
+ template error it keys nothing: a message that quietly dropped the part that
150
+ looped would go on the air looking fine. A label may name its own message;
151
+ only a message being SENT is part of the chain.
152
+
103
153
  ## Timestamps
104
154
 
105
155
  Two forms, and the rule is worth learning once:
@@ -146,6 +196,23 @@ operation at an unlisted park would print as though it had none. Liquid's own
146
196
  `array_to_sentence_string` is the near miss for `sentence`: it always writes
147
197
  the serial comma (`A, B, & C`).
148
198
 
199
+ ### Fallbacks
200
+
201
+ `default` chains, taking the first value that isn't blank — and the values
202
+ above are `""` when there is nothing to say, which counts as blank:
203
+
204
+ ```liquid
205
+ {{ qso.their.state | default: qso.their.guess.state | default: qso.their.county | default: "none" }}
206
+ ```
207
+
208
+ The same as a tag, for when each branch wants more than one value. Compare
209
+ against `blank` rather than testing the bare value: in Liquid only `nil` and
210
+ `false` are false, so `{% if "" %}` takes the branch and prints nothing.
211
+
212
+ ```liquid
213
+ {% if qso.their.state != blank %}{{ qso.their.state }}{% elsif qso.their.county != blank %}{{ qso.their.county }}{% else %}none{% endif %}
214
+ ```
215
+
149
216
  `alnum` is app-polo's `compact` helper under a different name: Liquid already
150
217
  has a `compact` (it drops nils from an **array**, and `op.refs`/`qso.refs` are
151
218
  arrays), and `registerFilter` overwrites without warning, so taking that name
@@ -224,7 +291,7 @@ will jump rather than count. Show HH:MM.
224
291
  | Panel documents | `custom-text`'s content and tab name | by the operator, in the panel's config form |
225
292
  | Export filenames and titles | Registered export types and `sdk/src/exportSettings.ts` | Settings → Exports, globally and per type |
226
293
  | ADIF NOTES / COMMENT / QSLMSG | Export type settings, consumed by `core/adif` | Settings → Exports; empty templates suppress a field |
227
- | CW messages | Radio settings `cwMessage1..8`, keyed on F1-F8 through the radio (docs/design/cat.md § CW keying) — rendered by the `template` hook (hooks.md) | by the operator, in the Station dialog's Messages… dialog |
294
+ | CW messages | Radio settings `cwMessage1..8`, keyed on F1-F8 through the radio (docs/design/cat.md § CW keying) — rendered by the `template` hook (hooks.md) | by the operator, in the CW Keyer dialog (Settings → Radio, or the Station dialog's keyer row) |
228
295
 
229
296
  NOTES and COMMENT default to QSO notes and are withheld when private data
230
297
  is off. QSLMSG defaults to empty for program exports, and for the whole-log
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ham2k/extension-sdk",
3
- "version": "0.5.7",
3
+ "version": "0.7.0",
4
4
  "description": "Write extensions for the Ham2K Logger: typed hook contracts and the host API",
5
5
  "keywords": [
6
6
  "ham2k",
@@ -39,6 +39,10 @@
39
39
  "types": "./dist/index.d.ts",
40
40
  "default": "./dist/index.js"
41
41
  },
42
+ "./timers": {
43
+ "ham2k-source": "./src/timers.ts",
44
+ "default": "./dist/timers.js"
45
+ },
42
46
  "./package.json": "./package.json"
43
47
  },
44
48
  "types": "./dist/index.d.ts",