@fraqjs/fraq 0.4.0 → 0.5.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.d.mts CHANGED
@@ -5507,6 +5507,58 @@ type Pattern = Record<string, Parameter<any>>;
5507
5507
  type ParamsOf<P extends Pattern> = { [K in keyof P]: P[K] extends Parameter<infer T> ? T : never };
5508
5508
  type Handler<P extends Pattern> = (session: Session, params: ParamsOf<P>) => void | Promise<void>;
5509
5509
  type SessionPredicate = (session: Session) => boolean;
5510
+ interface Command {
5511
+ name: string;
5512
+ pattern: Pattern;
5513
+ handler: (session: Session, params: any) => void | Promise<void>;
5514
+ }
5515
+ interface RawPattern {
5516
+ pattern: Pattern;
5517
+ handler: (session: Session, params: any) => void | Promise<void>;
5518
+ }
5519
+ type RouteEntry =
5520
+ | {
5521
+ type: 'command';
5522
+ command: Command;
5523
+ }
5524
+ | {
5525
+ type: 'group';
5526
+ name: string;
5527
+ router: Router;
5528
+ }
5529
+ | {
5530
+ type: 'filter';
5531
+ predicate: SessionPredicate;
5532
+ router: Router;
5533
+ }
5534
+ | {
5535
+ type: 'rawPattern';
5536
+ rawPattern: RawPattern;
5537
+ };
5538
+ type RouteBranch =
5539
+ | {
5540
+ type: 'command';
5541
+ path: string[];
5542
+ command: Command;
5543
+ }
5544
+ | {
5545
+ type: 'rawPattern';
5546
+ path: string[];
5547
+ rawPattern: RawPattern;
5548
+ };
5549
+ type RouteMatchResult =
5550
+ | {
5551
+ type: 'command';
5552
+ path: string[];
5553
+ command: Command;
5554
+ params: any;
5555
+ }
5556
+ | {
5557
+ type: 'rawPattern';
5558
+ path: string[];
5559
+ rawPattern: RawPattern;
5560
+ params: any;
5561
+ };
5510
5562
  interface Session {
5511
5563
  raw: IncomingMessage;
5512
5564
  reply(segments: OutgoingSegment_ZodInput[]): Promise<void>;
@@ -5518,12 +5570,16 @@ declare class Router {
5518
5570
  rawPattern<P extends Pattern>(pattern: P, handler: Handler<P>): this;
5519
5571
  group(name: string): Router;
5520
5572
  filter(predicate: SessionPredicate): Router;
5573
+ routes(): RouteEntry[];
5574
+ branches(session: Session): RouteBranch[];
5575
+ match(session: Session, message: IncomingMessage): RouteMatchResult | undefined;
5521
5576
  dispatch(session: Session, message: IncomingMessage): Promise<boolean>;
5522
- private process;
5523
- private processEntry;
5524
- private processCommand;
5525
- private processGroup;
5526
- private processRawPattern;
5577
+ private matchFrom;
5578
+ private matchEntry;
5579
+ private matchCommand;
5580
+ private matchGroup;
5581
+ private matchRawPattern;
5582
+ private branchesFrom;
5527
5583
  private capturePattern;
5528
5584
  }
5529
5585
  //#endregion
@@ -5688,11 +5744,13 @@ declare namespace seg {
5688
5744
  //#endregion
5689
5745
  export {
5690
5746
  ApiEndpoints,
5747
+ Command,
5691
5748
  Context,
5692
5749
  ContextOptions,
5693
5750
  ContextUrlOptions,
5694
5751
  EventMap,
5695
5752
  Filter,
5753
+ Handler,
5696
5754
  Injection,
5697
5755
  LogHandler,
5698
5756
  LogLevel,
@@ -5702,10 +5760,17 @@ export {
5702
5760
  MilkyEventSubscription,
5703
5761
  Parameter,
5704
5762
  ParameterList,
5763
+ ParamsOf,
5764
+ Pattern,
5705
5765
  Plugin,
5766
+ RawPattern,
5767
+ RouteBranch,
5768
+ RouteEntry,
5769
+ RouteMatchResult,
5706
5770
  Router,
5707
5771
  type ServiceClass,
5708
5772
  Session,
5773
+ SessionPredicate,
5709
5774
  combineLogHandlers,
5710
5775
  createMilkyClient,
5711
5776
  definePlugin,
package/dist/index.mjs CHANGED
@@ -211,49 +211,102 @@ var Router = class Router {
211
211
  });
212
212
  return router;
213
213
  }
214
- async dispatch(session, message) {
214
+ routes() {
215
+ return this.entries;
216
+ }
217
+ branches(session) {
218
+ return this.branchesFrom(session, []);
219
+ }
220
+ match(session, message) {
215
221
  const tokenizer = new Tokenizer(message.segments);
216
- return await this.process(session, tokenizer);
222
+ return this.matchFrom(session, tokenizer, []);
223
+ }
224
+ async dispatch(session, message) {
225
+ const match = this.match(session, message);
226
+ if (match === void 0) return false;
227
+ switch (match.type) {
228
+ case "command":
229
+ await match.command.handler(session, match.params);
230
+ break;
231
+ case "rawPattern":
232
+ await match.rawPattern.handler(session, match.params);
233
+ break;
234
+ }
235
+ return true;
217
236
  }
218
- async process(session, tokenizer) {
237
+ matchFrom(session, tokenizer, path) {
219
238
  const initialState = tokenizer.getState();
220
239
  for (const entry of this.entries) {
221
240
  tokenizer.setState(initialState);
222
- if (await this.processEntry(entry, session, tokenizer)) return true;
241
+ const match = this.matchEntry(entry, session, tokenizer, path);
242
+ if (match !== void 0) return match;
223
243
  }
224
244
  tokenizer.setState(initialState);
225
- return false;
226
245
  }
227
- async processEntry(entry, session, tokenizer) {
246
+ matchEntry(entry, session, tokenizer, path) {
228
247
  switch (entry.type) {
229
- case "command": return await this.processCommand(entry.command, session, tokenizer);
230
- case "group": return await this.processGroup(entry.name, entry.router, session, tokenizer);
248
+ case "command": return this.matchCommand(entry.command, tokenizer, path);
249
+ case "group": return this.matchGroup(entry.name, entry.router, session, tokenizer, path);
231
250
  case "filter":
232
- if (entry.predicate(session) !== true) return false;
233
- return await entry.router.process(session, tokenizer);
234
- case "rawPattern": return await this.processRawPattern(entry.rawPattern, session, tokenizer);
251
+ if (entry.predicate(session) !== true) return;
252
+ return entry.router.matchFrom(session, tokenizer, path);
253
+ case "rawPattern": return this.matchRawPattern(entry.rawPattern, tokenizer, path);
235
254
  }
236
255
  }
237
- async processCommand(command, session, tokenizer) {
256
+ matchCommand(command, tokenizer, path) {
238
257
  const token = tokenizer.peek();
239
- if (typeof token !== "string" || token !== command.name) return false;
258
+ if (typeof token !== "string" || token !== command.name) return;
240
259
  tokenizer.next();
241
260
  const params = this.capturePattern(command.pattern, tokenizer);
242
- if (params === void 0 || tokenizer.hasNext()) return false;
243
- await command.handler(session, params);
244
- return true;
261
+ if (params === void 0 || tokenizer.hasNext()) return;
262
+ return {
263
+ type: "command",
264
+ path: [...path],
265
+ command,
266
+ params
267
+ };
245
268
  }
246
- async processGroup(name, router, session, tokenizer) {
269
+ matchGroup(name, router, session, tokenizer, path) {
247
270
  const token = tokenizer.peek();
248
- if (typeof token !== "string" || token !== name) return false;
271
+ if (typeof token !== "string" || token !== name) return;
249
272
  tokenizer.next();
250
- return await router.process(session, tokenizer);
273
+ return router.matchFrom(session, tokenizer, [...path, name]);
251
274
  }
252
- async processRawPattern(rawPattern, session, tokenizer) {
275
+ matchRawPattern(rawPattern, tokenizer, path) {
253
276
  const params = this.capturePattern(rawPattern.pattern, tokenizer);
254
- if (params === void 0 || tokenizer.hasNext()) return false;
255
- await rawPattern.handler(session, params);
256
- return true;
277
+ if (params === void 0 || tokenizer.hasNext()) return;
278
+ return {
279
+ type: "rawPattern",
280
+ path: [...path],
281
+ rawPattern,
282
+ params
283
+ };
284
+ }
285
+ branchesFrom(session, path) {
286
+ const branches = [];
287
+ for (const entry of this.entries) switch (entry.type) {
288
+ case "command":
289
+ branches.push({
290
+ type: "command",
291
+ path: [...path],
292
+ command: entry.command
293
+ });
294
+ break;
295
+ case "group":
296
+ branches.push(...entry.router.branchesFrom(session, [...path, entry.name]));
297
+ break;
298
+ case "filter":
299
+ if (entry.predicate(session) === true) branches.push(...entry.router.branchesFrom(session, path));
300
+ break;
301
+ case "rawPattern":
302
+ branches.push({
303
+ type: "rawPattern",
304
+ path: [...path],
305
+ rawPattern: entry.rawPattern
306
+ });
307
+ break;
308
+ }
309
+ return branches;
257
310
  }
258
311
  capturePattern(pattern, tokenizer) {
259
312
  const initialState = tokenizer.getState();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fraqjs/fraq",
3
3
  "type": "module",
4
- "version": "0.4.0",
4
+ "version": "0.5.0",
5
5
  "description": "Milky Bot framework",
6
6
  "files": [
7
7
  "dist"
@@ -19,6 +19,9 @@
19
19
  "dependencies": {
20
20
  "mitt": "^3.0.1"
21
21
  },
22
+ "devDependencies": {
23
+ "@fraqjs/mock": "^0.1.0"
24
+ },
22
25
  "engines": {
23
26
  "node": ">=22"
24
27
  },