@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/AGENTS.md +6 -0
- package/dist/base64.js +38 -0
- package/dist/copyOnWrite.js +71 -0
- package/dist/hookCategories.js +25 -0
- package/dist/index.d.ts +92 -6
- package/dist/index.js +110 -0
- package/dist/scoring.js +53 -14
- package/dist/templateContext.js +43 -2
- package/dist/timerQueue.js +187 -0
- package/dist/timers.js +42 -0
- package/docs/distribution.md +27 -6
- package/docs/hooks.md +135 -32
- package/docs/templates.md +69 -2
- package/package.json +5 -1
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
|
|
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.
|
|
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",
|