@super-line/plugin-inspector 0.1.0 → 0.2.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/dist/index.cjs CHANGED
@@ -38,14 +38,17 @@ var encoder = new TextEncoder();
38
38
  function encodedByteSize(encoded) {
39
39
  return typeof encoded === "string" ? encoder.encode(encoded).length : encoded.byteLength;
40
40
  }
41
- async function buildInspectedContract(contract) {
42
- let toJsonSchema;
41
+ async function loadJsonConverter() {
43
42
  try {
44
43
  const mod = await import("@standard-community/standard-json");
45
- toJsonSchema = mod.toJsonSchema;
44
+ return mod.toJsonSchema;
46
45
  } catch {
47
- return (0, import_core.classifyContract)(contract);
46
+ return null;
48
47
  }
48
+ }
49
+ async function buildInspectedContract(contract) {
50
+ const toJsonSchema = await loadJsonConverter();
51
+ if (!toJsonSchema) return (0, import_core.classifyContract)(contract);
49
52
  const schemas = /* @__PURE__ */ new Set();
50
53
  (0, import_core.classifyContract)(contract, (s) => {
51
54
  schemas.add(s);
@@ -66,6 +69,24 @@ async function buildInspectedContract(contract) {
66
69
  );
67
70
  return (0, import_core.classifyContract)(contract, (s) => converted.get(s));
68
71
  }
72
+ async function buildCollectionInfos(contract, infos) {
73
+ const toJsonSchema = await loadJsonConverter();
74
+ const defs = contract.collections ?? {};
75
+ return Promise.all(
76
+ infos.map(async (info) => {
77
+ const schema = defs[info.name]?.schema;
78
+ let json;
79
+ if (toJsonSchema && schema) {
80
+ try {
81
+ json = await toJsonSchema(schema);
82
+ } catch {
83
+ json = void 0;
84
+ }
85
+ }
86
+ return { ...info, ...json !== void 0 ? { schema: json } : {} };
87
+ })
88
+ );
89
+ }
69
90
  function inspector(opts = {}) {
70
91
  const redact = new Set(opts.redact ?? []);
71
92
  function safeSnapshot(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
@@ -104,7 +125,6 @@ function inspector(opts = {}) {
104
125
  case "msg.event":
105
126
  case "msg.broadcast":
106
127
  case "msg.publish":
107
- case "store.write":
108
128
  return { ...event, data: safeSnapshot(event.data) };
109
129
  default:
110
130
  return event;
@@ -157,31 +177,21 @@ function inspector(opts = {}) {
157
177
  if (!remote) throw new import_core.SuperLineError("NOT_FOUND", `Unknown connection: ${id}`);
158
178
  return { descriptor: remote, ctxAvailable: false };
159
179
  },
160
- listStores: async () => ctx.storeInfos(),
161
- listResources: async (input) => {
162
- const { store: name, ...opts2 } = input;
163
- if (!ctx.storeInfos().some((s) => s.name === name)) throw new import_core.SuperLineError("NOT_FOUND", `Unknown store: ${name}`);
164
- return ctx.store(name).list(opts2);
165
- },
166
- searchPrincipals: async (input) => {
167
- const { store: name, ...opts2 } = input;
168
- if (!ctx.storeInfos().some((s) => s.name === name)) throw new import_core.SuperLineError("NOT_FOUND", `Unknown store: ${name}`);
169
- return ctx.store(name).searchPrincipals(opts2);
170
- },
171
- readResource: async (input) => {
172
- const { store: name, id } = input;
173
- if (!ctx.storeInfos().some((s) => s.name === name)) throw new import_core.SuperLineError("NOT_FOUND", `Unknown store: ${name}`);
174
- const handle = ctx.store(name);
175
- const resource = await handle.read(id);
176
- if (!resource) throw new import_core.SuperLineError("NOT_FOUND", `No resource: ${name}/${id}`);
177
- let data = resource.data;
178
- try {
179
- const replica = handle.open(id);
180
- data = replica.getSnapshot();
181
- replica.close();
182
- } catch {
180
+ listCollections: () => buildCollectionInfos(ctx.contract, ctx.collectionInfos()),
181
+ queryCollection: async (input) => {
182
+ const { collection, ...query } = input;
183
+ const def = ctx.contract.collections?.[collection];
184
+ if (!def) throw new import_core.SuperLineError("NOT_FOUND", `Unknown collection: ${collection}`);
185
+ if ((0, import_core.isCrdtCollection)(def)) {
186
+ const handle = ctx.collection(collection);
187
+ const docs = await handle.list({ limit: query.limit, offset: query.offset });
188
+ const rows2 = await Promise.all(
189
+ docs.map(async (d) => ({ id: d.id, ...await handle.read(d.id) }))
190
+ );
191
+ return rows2.map((r) => safeSnapshot(r));
183
192
  }
184
- return { data: safeSnapshot(data), accessRules: resource.accessRules };
193
+ const rows = await ctx.collection(collection).snapshot(query);
194
+ return rows.map((r) => safeSnapshot(r));
185
195
  }
186
196
  })
187
197
  }
package/dist/index.d.cts CHANGED
@@ -6,7 +6,7 @@ interface InspectorOptions {
6
6
  redact?: string[];
7
7
  }
8
8
  /**
9
- * The Control Center inspector, packaged as a plugin. It taps every request/event/store write, snapshots +
9
+ * The Control Center inspector, packaged as a plugin. It taps every request/event, snapshots +
10
10
  * field-redacts the payloads, and publishes them (cluster-wide) on its own plugin channel; and it declares a
11
11
  * plugin-owned, observer-invisible connection class (the `superline.inspector.v1` subprotocol) that serves
12
12
  * Control Center clients the `InspectorContract` — `getContract`, `getTopology`, `getConn`, … and the
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ interface InspectorOptions {
6
6
  redact?: string[];
7
7
  }
8
8
  /**
9
- * The Control Center inspector, packaged as a plugin. It taps every request/event/store write, snapshots +
9
+ * The Control Center inspector, packaged as a plugin. It taps every request/event, snapshots +
10
10
  * field-redacts the payloads, and publishes them (cluster-wide) on its own plugin channel; and it declares a
11
11
  * plugin-owned, observer-invisible connection class (the `superline.inspector.v1` subprotocol) that serves
12
12
  * Control Center clients the `InspectorContract` — `getContract`, `getTopology`, `getConn`, … and the
package/dist/index.js CHANGED
@@ -5,20 +5,24 @@ import {
5
5
  INSPECTOR_SUBPROTOCOL,
6
6
  InspectorContract,
7
7
  classifyContract,
8
- eventPayload
8
+ eventPayload,
9
+ isCrdtCollection
9
10
  } from "@super-line/core";
10
11
  var encoder = new TextEncoder();
11
12
  function encodedByteSize(encoded) {
12
13
  return typeof encoded === "string" ? encoder.encode(encoded).length : encoded.byteLength;
13
14
  }
14
- async function buildInspectedContract(contract) {
15
- let toJsonSchema;
15
+ async function loadJsonConverter() {
16
16
  try {
17
17
  const mod = await import("@standard-community/standard-json");
18
- toJsonSchema = mod.toJsonSchema;
18
+ return mod.toJsonSchema;
19
19
  } catch {
20
- return classifyContract(contract);
20
+ return null;
21
21
  }
22
+ }
23
+ async function buildInspectedContract(contract) {
24
+ const toJsonSchema = await loadJsonConverter();
25
+ if (!toJsonSchema) return classifyContract(contract);
22
26
  const schemas = /* @__PURE__ */ new Set();
23
27
  classifyContract(contract, (s) => {
24
28
  schemas.add(s);
@@ -39,6 +43,24 @@ async function buildInspectedContract(contract) {
39
43
  );
40
44
  return classifyContract(contract, (s) => converted.get(s));
41
45
  }
46
+ async function buildCollectionInfos(contract, infos) {
47
+ const toJsonSchema = await loadJsonConverter();
48
+ const defs = contract.collections ?? {};
49
+ return Promise.all(
50
+ infos.map(async (info) => {
51
+ const schema = defs[info.name]?.schema;
52
+ let json;
53
+ if (toJsonSchema && schema) {
54
+ try {
55
+ json = await toJsonSchema(schema);
56
+ } catch {
57
+ json = void 0;
58
+ }
59
+ }
60
+ return { ...info, ...json !== void 0 ? { schema: json } : {} };
61
+ })
62
+ );
63
+ }
42
64
  function inspector(opts = {}) {
43
65
  const redact = new Set(opts.redact ?? []);
44
66
  function safeSnapshot(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
@@ -77,7 +99,6 @@ function inspector(opts = {}) {
77
99
  case "msg.event":
78
100
  case "msg.broadcast":
79
101
  case "msg.publish":
80
- case "store.write":
81
102
  return { ...event, data: safeSnapshot(event.data) };
82
103
  default:
83
104
  return event;
@@ -130,31 +151,21 @@ function inspector(opts = {}) {
130
151
  if (!remote) throw new SuperLineError("NOT_FOUND", `Unknown connection: ${id}`);
131
152
  return { descriptor: remote, ctxAvailable: false };
132
153
  },
133
- listStores: async () => ctx.storeInfos(),
134
- listResources: async (input) => {
135
- const { store: name, ...opts2 } = input;
136
- if (!ctx.storeInfos().some((s) => s.name === name)) throw new SuperLineError("NOT_FOUND", `Unknown store: ${name}`);
137
- return ctx.store(name).list(opts2);
138
- },
139
- searchPrincipals: async (input) => {
140
- const { store: name, ...opts2 } = input;
141
- if (!ctx.storeInfos().some((s) => s.name === name)) throw new SuperLineError("NOT_FOUND", `Unknown store: ${name}`);
142
- return ctx.store(name).searchPrincipals(opts2);
143
- },
144
- readResource: async (input) => {
145
- const { store: name, id } = input;
146
- if (!ctx.storeInfos().some((s) => s.name === name)) throw new SuperLineError("NOT_FOUND", `Unknown store: ${name}`);
147
- const handle = ctx.store(name);
148
- const resource = await handle.read(id);
149
- if (!resource) throw new SuperLineError("NOT_FOUND", `No resource: ${name}/${id}`);
150
- let data = resource.data;
151
- try {
152
- const replica = handle.open(id);
153
- data = replica.getSnapshot();
154
- replica.close();
155
- } catch {
154
+ listCollections: () => buildCollectionInfos(ctx.contract, ctx.collectionInfos()),
155
+ queryCollection: async (input) => {
156
+ const { collection, ...query } = input;
157
+ const def = ctx.contract.collections?.[collection];
158
+ if (!def) throw new SuperLineError("NOT_FOUND", `Unknown collection: ${collection}`);
159
+ if (isCrdtCollection(def)) {
160
+ const handle = ctx.collection(collection);
161
+ const docs = await handle.list({ limit: query.limit, offset: query.offset });
162
+ const rows2 = await Promise.all(
163
+ docs.map(async (d) => ({ id: d.id, ...await handle.read(d.id) }))
164
+ );
165
+ return rows2.map((r) => safeSnapshot(r));
156
166
  }
157
- return { data: safeSnapshot(data), accessRules: resource.accessRules };
167
+ const rows = await ctx.collection(collection).snapshot(query);
168
+ return rows.map((r) => safeSnapshot(r));
158
169
  }
159
170
  })
160
171
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@super-line/plugin-inspector",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Control Center inspector for super-line, packaged as a plugin — taps + a plugin-owned CC connection.",
6
6
  "license": "MIT",
@@ -46,13 +46,13 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@standard-community/standard-json": "^0.3.5",
49
- "@super-line/core": "^0.10.0"
49
+ "@super-line/core": "^0.11.0"
50
50
  },
51
51
  "peerDependencies": {
52
- "@super-line/server": "^0.10.0"
52
+ "@super-line/server": "^0.11.0"
53
53
  },
54
54
  "devDependencies": {
55
- "@super-line/server": "^0.10.0"
55
+ "@super-line/server": "^0.11.0"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsup"