# redis-array-playground

Build artefacts and rebuild scripts for `../redis-array.html`, an in-browser
playground for the new Redis Array type proposed in
[redis/redis#15162](https://github.com/redis/redis/pull/15162) (see also
antirez's writeup at [antirez.com/news/164](https://antirez.com/news/164)).

## What runs where

The playground compiles **the unmodified `t_array.c`, `sparsearray.c`,
`util.c`, `sds.c`, `fast_float_strtod.c`, `fpconv_dtoa.c` and `sha256.c`**
from the [`antirez:array`](https://github.com/antirez/redis/tree/array)
branch, plus the bundled **TRE** regex library from `deps/tre/`, into a
single WebAssembly module.

JavaScript on the page only:

1. Builds the `argv` blob from the form inputs.
2. Calls `wasm_dispatch(cmd_index, argv_blob)`.
3. Decodes the typed reply buffer the C code writes into shared memory.
4. Renders that reply.

There is **no JS reimplementation of any AR\* command** — every iteration,
predicate, regex match and aggregation runs from the actual Redis sources
on the array branch:

- `arScanIter` from `t_array.c` drives `ARSCAN`, `ARGREP` and `AROP`.
- `tre_regncompb` / `tre_regnexecb` from the vendored TRE library handle
  `ARGREP RE`.
- `stringmatchlen` from `util.c` handles `ARGREP GLOB`.
- `arEncode` / `arDecode` from `sparsearray.c` handle the tagged-pointer
  value packing.

Replies use the same `addReply*` family as a real Redis server; the only
difference is that the stub `addReply*` writes records into a tagged
binary buffer instead of a TCP connection.

## Files

| File | Origin | Notes |
|---|---|---|
| `redis-array.js` | generated by `build_wasm.sh` | SINGLE\_FILE Emscripten module — embeds the wasm binary as base64. ~145 KB. |
| `ar-commands.json` | generated by `build_commands.py` | All `src/commands/ar*.json` definitions merged into one file. Drives the dynamic forms in the HTML. |
| `src-stub/server.h` | hand-written | Minimal subset of Redis' `server.h`: declares only what `t_array.c` and `util.c` actually reference. |
| `src-stub/redis_stubs.c` | hand-written | Tiny Redis runtime: `zmalloc`, an `sds`-keyed dict for the keyspace, and `addReply*` writing into a tagged binary buffer. |
| `src-stub/wasm_entry.c` | hand-written | JS-callable entry points: `wasm_init`, `wasm_dispatch`, `wasm_reply_buf_*`, `wasm_list_keys`, `wasm_key_stats`, `wasm_drop_key`, `wasm_flush_all`. |
| `build_wasm.sh` | hand-written | Reproducible Emscripten build — copies the Redis sources into a temp dir, then links them with the stub. |
| `build_commands.py` | hand-written | Combines `src/commands/ar*.json` into `ar-commands.json`. |

The reply wire format the C side emits is documented at the top of
`redis_stubs.c`; the JS-side decoder lives in `WasmEngine._decode` inside
`../redis-array.html`.

## What's *not* in the build

The WASM module deliberately stops short of being a full `redis-server`.
Networking, threading, eval/scripting, persistence (RDB/AOF), replication,
cluster, pubsub, modules, expiration and ACL are all absent. The array
type doesn't depend on them, so they're stubbed where t\_array.c happens
to call them (`signalModifiedKey`, `notifyKeyspaceEvent`,
`updateKeysizesHist`, `updateSlotAllocSize`, `keyModified`,
`kvobjAllocSize` are all no-ops). This keeps the bundle around 65 KB
gzipped instead of multiple MB.

## Rebuilding

```bash
# Get the array branch
git clone https://github.com/redis/redis /tmp/redis
git -C /tmp/redis remote add antirez https://github.com/antirez/redis
git -C /tmp/redis fetch antirez array
git -C /tmp/redis checkout -b array antirez/array

# Combined command catalog
python3 build_commands.py /tmp/redis ar-commands.json

# WASM bundle (requires emscripten activated on PATH)
./build_wasm.sh /tmp/redis
```

The playground HTML at `../redis-array.html` fetches both files at runtime.
