npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xudesheng/alwayson-js-codec

v0.1.4

Published

Minimal JS/WASM-focused ThingWorx AlwaysOn codec

Readme

alwayson-js-codec

alwayson-js-codec is a small, publishable AlwaysOn protocol codec for JavaScript and WebAssembly.

This repository exists because we want a public, focused codec library that can power a lightweight ThingWorx AlwaysOn client in ai-parler without exposing or depending on the author's broader private Rust prototype. The long-term goal is:

  • keep this repo narrowly scoped to protocol encoding/decoding
  • keep transport/session logic in JavaScript, close to the widget that uses it
  • make it obvious how ai-parler can build a Parler-specific AlwaysOn client on top

Why This Repo Exists

The original exploration happened in a private Rust repository that implements a fuller AlwaysOn codec. That private work is the historical source of truth for the ideas here, but this repo is intended to be:

  • safe to publish
  • small enough to understand quickly
  • intentionally designed for JS/WASM consumption

This repo is not trying to become a second tw-javascript-sdk.

Scope

This crate is responsible for:

  • binary encoding/decoding of core AlwaysOn messages
  • message header handling
  • auth and bind message bodies
  • a JS/WASM-friendly API surface
  • documentation that explains how to pair this codec with a thin browser transport/session shell

This crate is not responsible for:

  • WebSocket lifecycle management
  • reconnect logic
  • heartbeat scheduling
  • callback registries
  • widget UI state
  • Parler business logic

Current Status

This is the initial bootstrap of the public-facing crate.

Implemented now:

  • core message header
  • auth body codec
  • bind body codec
  • unbind support using the same body shape as bind, but with explicit unbind semantics in the public API
  • request / response body codec
  • common ThingWorx response/error status codes beyond plain Success
  • minimal InfoTable / DataShape / primitive support for service calls
  • minimal top-level message builders
  • a framed parse_inbound_message(...) helper for browser shells
  • multipart chunk parsing, splitting, and merging aligned with tw-javascript-sdk
  • outbound multipart helpers that can emit ready-to-send on-wire chunk bytes
  • first-pass wasm-bindgen exports
  • fixed interop fixtures for auth, bind, and error response decoding

Planned next:

  • JS wrapper ergonomics
  • examples showing integration from ai-parler

Relationship To Other Repos

  • ../rust/alwayson-codec Private source of prior exploration. This repo intentionally copies only the minimum necessary code and reshapes it for public JS/WASM use.
  • ../parler Home of ai-parler, where the browser transport/session shell should live.
  • ../twx-agent-extension The ThingWorx server-side extension whose AlwaysOn usage drove this work.

Design Direction

The intended architecture is:

  1. alwayson-js-codec handles protocol bytes and message objects.
  2. ai-parler provides a thin browser transport/session shell around native WebSocket.
  3. That shell implements only the minimum client behavior needed by Parler:
    • open socket
    • send auth
    • send bind
    • maintain requestId, sessionId, endpointId
    • dispatch incoming requests
    • respond to GetMetadata, SynchronizeModelState, and ReceiveMessage

The current crate already includes a one-shot inbound parser so the JS shell does not need to hand-roll header/body offset math before dispatching service requests or responses. That parser assumes the input slice starts at a message boundary. If a browser transport sees coalesced or partial binary frames, it should buffer data in JavaScript, call parse_inbound_message(...) only at offset 0, then advance by consumed.

For the wider Parler naming context, see the sibling server-side design note in ../twx-agent-extension/docs/parler-gateway-design.md, especially the gateway-vs-conversation discussion around section 2.2.

For auth-like inbound messages, parse_inbound_message(...) now distinguishes:

  • kind: "auth" when header.code is Auth
  • kind: "clear_auth" when header.code is ClearAuth

For build_response_message(...), the status_code argument is the raw AlwaysOn response opcode. Common values:

| Code | Name | |------|------| | 0x40 | Success | | 0x80 | BadRequest | | 0x84 | NotFound | | 0x85 | MethodNotAllowed | | 0xA0 | InternalError | | 0xA3 | ServiceUnavailable | | 0xA5 | NotImplemented |

Multipart helpers now available in the WASM surface:

  • parse_multipart_chunk(...)
  • split_multipart_message(...)
  • encode_multipart_chunk(...)
  • split_multipart_message_bytes(...)
  • merge_multipart_chunks_bytes(...)
  • merge_multipart_chunks_json(...)

For outbound multipart sends, the JS shell can now choose either path:

  • call split_multipart_message(...), then encode individual JSON chunks with encode_multipart_chunk(...)
  • or call split_multipart_message_bytes(...) to get ready-to-send on-wire chunk frames directly

Multipart compatibility note:

  • alwayson-js-codec intentionally follows the tw-javascript-sdk multipart family for browser parity.
  • Historical ThingWorx clients are not perfectly uniform here: the C SDK and the author's earlier private Rust prototype use a different on-wire multipart shape in some cases.
  • For Parler and other browser-side consumers, this crate treats JS/browser parity as the compatibility target rather than trying to produce both multipart wire layouts at once.

Blob note:

  • TwPrim::Blob in this crate is raw u32 length + bytes.
  • tw-javascript-sdk higher-level Blob helpers commonly use base64 strings.
  • If the JS shell needs SDK-style Blob behavior, convert base64 at the shell boundary before calling this codec.

Repository Guide

  • Read docs/spec.md first.
  • Read AGENTS.md if you are using an AI coding tool.
  • Keep this repo codec-focused. Do not move browser runtime logic into Rust unless there is a very strong reason.

Polite Note To Future Maintainers

Thanks for taking a look at this project.

If you are here because you want a tiny, understandable AlwaysOn codec that is friendlier to JS/WASM than a full client SDK, you are in the right place. If you need a complete transport/session runtime, this repo should help you build one, but it should not quietly turn into one itself.