vue-cot
Vue 3 CoT protocol library
A focused Vue 3 library for Cursor on Target (CoT), the messaging protocol spoken across the ATAK / WinTAK / TAK Server ecosystem. Pure parser and serialiser, typed models for the CoT event tree, WebSocket lifecycle with reconnection and keepalive, a reactive Pinia entity store, and three custom Pinia plugins, all shipped as a real npm package with dual ESM + CJS output, strict TypeScript, and round-trip tests.
Development duration
2026
Role
Sole Developer
Tools
Vue 3, TypeScript, Pinia, tsup, Vitest
Type
Open-source npm library
Dual ESM + CJS
Package output
Strict TS
TypeScript
v0.1.1
Published version
Round-trip tested
Coverage
WebSocket lifecycle:
A layered set of composables: a raw socket, then reconnection with exponential backoff + jitter (to survive network flaps without a thundering herd), then a TAK connection layer with application-level keepalive, zombie-connection detection, and newline-delimited message framing.
The CoT protocol:
A pure, fully-typed parser and serialiser (parseCoT / serializeCoT), typed models for the CoT event tree, and a decoder for the a-f-G-U-C-I type grammar, all Vue-free and unit-tested, including round-trip tests. parseCoT now throws on missing uid or type, so consumers get a real error instead of a silent "undefined".
Pinia at scale:
A reactive entity store (Map<uid, Entity>) with a single requestAnimationFrame TTL sweep, so thousands of entities expire without a timer each. Wrapped in Pinia stores with cross-store composition, plus three custom Pinia plugins written from scratch: localStorage persistence, cross-tab sync via BroadcastChannel, and an action logger.
Closing the loop with vue-tactical-demo:
This library was born inside a live map app (vue-tactical-demo). Once vue-cot was published, I refactored the demo to consume the library, replacing its inline DOMParser parsing with a call to parseCoT. Dogfooding it that way surfaced a real gap: parseCoT did not validate a missing uid or type. I patched the library (thrown errors on missing fields, shipped as v0.1.1) and simplified the demo against the patch. That full cycle: real app finds a gap → library patch → app simplifies against it. It's what makes this a library and not just a code dump.
Vue Tactical Demo →