# diigo-dump Cloudflare Worker port of [`diigo-dump.mjs` in the mm-diigo repo](https://github.com/dckc/mm-diigo) (`projects/diigo-bak/diigo-dump.mjs`) — dump Diigo bookmarks, most-recently-updated first, via the browser session cookie rather than the static API key. ## What it does One page: a page-number field and a dump button. Submitting POSTs to the worker, which fetches https://www.diigo.com/interact_api/load_user_items ?sort=updated&count=24&page_num= with the session cookie and shows status, `total`, and the JSON items in a read-only `
`. GET `/` is inert — dumps happen only on explicit submits.

## Structure: WebApp as a Durable Object (webapp worker)

The credentialed authority is a Durable Object instance from the separately
deployable `../webapp/` worker (service binding `WEBAPP` → its
`WebAppFactory` entrypoint; diigo knowledge = only the mint call in
`src/index.ts`). The instance is configured once — diigo's URL + seed
headers (cookie, UA, x-requested-with) + 500ms rate gate — and persists
its init in DO storage: it survives restarts, and diigo-dump or any other
worker can reconnect purely by id. The cookie crosses the wire exactly
once, at mint time.

Setup (dev):

    cd diigo-dump
    npx wrangler dev -c wrangler.jsonc -c ../webapp/wrangler.jsonc
    # → http://localhost:8787 (webapp is secondary, binding-only)

    npm run diigo-login >> .dev.vars   # askpass for the cookie, mints the
                                       # instance, writes DIIGO_COOKIE +
                                       # DIIGO_WEB_ID; then restart wrangler
    # or, no askpass: open http://localhost:8787/_connect and paste the
    # cookie into the mint form; it prints the DIIGO_WEB_ID line to add

Deployed:

    cd ../webapp && npx wrangler deploy
    cd ../diigo-dump && npx wrangler deploy
    npx wrangler secret put DIIGO_COOKIE   # re-run diigo-login only when
    npx wrangler secret put DIIGO_WEB_ID   # the cookie itself expires

Re-login is needed only when diigo invalidates the cookie; re-minting
(POST /_mint with the new cookie) yields a fresh id and no other changes.

Provenance notes: the `user-agent` / `x-requested-with` headers and the
`interact_api` endpoint mirror the original script; the fluent client from
`WebApp.js` is restored in `src/webapp.ts` with `WebApp` and the rate-limit
wrapper as `RpcTarget` subclasses. `src/diigo.ts` holds `makeDiigoAPI` and
the `dumpBookmarks` generator; `DiigoService.open()` hands an RPC caller a
rate-limited stub with the cookie attached only on the server side, and
promise pipelining makes a whole `pathjoin().query().get()` chain a single
round trip. One deliberate divergence from the original: `url` is a private
field, not a public property — on an `RpcTarget`, a public property is
readable over RPC (a property read is an argument-less method call), and a
query string can carry credentials, so a public `url` would leak them to any
stub holder.

## RPC use (from another worker, same account)

```jsonc
// wrangler.jsonc of the caller
"services": [{ "binding": "DIIGO", "service": "diigo-dump", "entrypoint": "DiigoService" }]
```

```ts
import { dumpBookmarks } from "./diigo.js";

const stub = env.DIIGO.open(); // rate-limited, cookie stays server-side
// pipeline: one round trip for the whole chain
const first = JSON.parse(await stub.pathjoin("load_user_items")
	.query({ sort: "updated", count: 24, page_num: 1 }).get());
// or run the whole dump in this worker's address space:
for await (const item of dumpBookmarks({ diigoAPI: stub, pages: 2 })) {
	console.log(item);
}
```

## Configuration

- Secret `DIIGO_COOKIE`: the `Cookie` header from diigo.com devtools.
  - Local dev: `.dev.vars` (gitignored). Note wrangler reads it only at
    startup — restart after edits.
  - Deployed: `npx wrangler secret put DIIGO_COOKIE`.

## Run

    cd diigo-dump
    npx wrangler dev -c wrangler.jsonc -c ../webapp/wrangler.jsonc
    # → http://localhost:8787; webapp rides along, binding-only
    # (first run: npm run diigo-login >> .dev.vars, or the /_connect page;
    # restart wrangler after adding DIIGO_WEB_ID)

Status as of 2026-10-06: manual integration test passes — 200, `total: 1674`.
See the project ladder in ../capsite-checklist.md; context in
../capsite-notes.md. This is the cookie path; the API-key path
(EmDash plugin) is still 401.