@rine-kit/pubg-domain 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +38 -2
- package/dist/config/default-team.json +27 -0
- package/dist/src/config/chicken-index.d.ts +9 -0
- package/dist/src/config/chicken-index.js +37 -0
- package/dist/src/config/chicken-index.js.map +1 -0
- package/dist/src/config/team.d.ts +22 -0
- package/dist/src/config/team.js +69 -0
- package/dist/src/config/team.js.map +1 -0
- package/dist/src/context/context-store.d.ts +40 -0
- package/dist/src/context/context-store.js +119 -0
- package/dist/src/context/context-store.js.map +1 -0
- package/dist/src/context/team-context.d.ts +13 -0
- package/dist/src/context/team-context.js +16 -0
- package/dist/src/context/team-context.js.map +1 -0
- package/dist/src/core.d.ts +23 -0
- package/dist/src/core.js +24 -0
- package/dist/src/core.js.map +1 -0
- package/dist/src/data/model.d.ts +123 -0
- package/dist/src/data/model.js +100 -0
- package/dist/src/data/model.js.map +1 -0
- package/dist/src/data/pubg-api-client.d.ts +59 -0
- package/dist/src/data/pubg-api-client.js +441 -0
- package/dist/src/data/pubg-api-client.js.map +1 -0
- package/dist/src/engine/query-engine.d.ts +20 -0
- package/dist/src/engine/query-engine.js +765 -0
- package/dist/src/engine/query-engine.js.map +1 -0
- package/dist/src/index.d.ts +27 -0
- package/dist/src/index.js +28 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/migration/importer.d.ts +35 -0
- package/dist/src/migration/importer.js +229 -0
- package/dist/src/migration/importer.js.map +1 -0
- package/dist/src/review/combat-scope.d.ts +11 -0
- package/dist/src/review/combat-scope.js +101 -0
- package/dist/src/review/combat-scope.js.map +1 -0
- package/dist/src/review/event-combination-engine.d.ts +17 -0
- package/dist/src/review/event-combination-engine.js +534 -0
- package/dist/src/review/event-combination-engine.js.map +1 -0
- package/dist/src/review/fight-detector.d.ts +4 -0
- package/dist/src/review/fight-detector.js +138 -0
- package/dist/src/review/fight-detector.js.map +1 -0
- package/dist/src/review/fight-integrity-validator.d.ts +13 -0
- package/dist/src/review/fight-integrity-validator.js +134 -0
- package/dist/src/review/fight-integrity-validator.js.map +1 -0
- package/dist/src/review/fun-candidate-generator.d.ts +9 -0
- package/dist/src/review/fun-candidate-generator.js +267 -0
- package/dist/src/review/fun-candidate-generator.js.map +1 -0
- package/dist/src/review/fun-event-generator.d.ts +8 -0
- package/dist/src/review/fun-event-generator.js +740 -0
- package/dist/src/review/fun-event-generator.js.map +1 -0
- package/dist/src/review/fun-intelligence.d.ts +13 -0
- package/dist/src/review/fun-intelligence.js +20 -0
- package/dist/src/review/fun-intelligence.js.map +1 -0
- package/dist/src/review/fun-ranker.d.ts +13 -0
- package/dist/src/review/fun-ranker.js +68 -0
- package/dist/src/review/fun-ranker.js.map +1 -0
- package/dist/src/review/heavy-weapon-intelligence.d.ts +5 -0
- package/dist/src/review/heavy-weapon-intelligence.js +215 -0
- package/dist/src/review/heavy-weapon-intelligence.js.map +1 -0
- package/dist/src/review/key-operation-detector.d.ts +3 -0
- package/dist/src/review/key-operation-detector.js +126 -0
- package/dist/src/review/key-operation-detector.js.map +1 -0
- package/dist/src/review/match-selector.d.ts +18 -0
- package/dist/src/review/match-selector.js +202 -0
- package/dist/src/review/match-selector.js.map +1 -0
- package/dist/src/review/review-analyzer.d.ts +2 -0
- package/dist/src/review/review-analyzer.js +652 -0
- package/dist/src/review/review-analyzer.js.map +1 -0
- package/dist/src/review/review-facts.d.ts +17 -0
- package/dist/src/review/review-facts.js +560 -0
- package/dist/src/review/review-facts.js.map +1 -0
- package/dist/src/review/review-share.d.ts +48 -0
- package/dist/src/review/review-share.js +37 -0
- package/dist/src/review/review-share.js.map +1 -0
- package/dist/src/review/selection-store.d.ts +25 -0
- package/dist/src/review/selection-store.js +80 -0
- package/dist/src/review/selection-store.js.map +1 -0
- package/dist/src/review/session-review.d.ts +72 -0
- package/dist/src/review/session-review.js +492 -0
- package/dist/src/review/session-review.js.map +1 -0
- package/dist/src/review/special-events.d.ts +3 -0
- package/dist/src/review/special-events.js +258 -0
- package/dist/src/review/special-events.js.map +1 -0
- package/dist/src/review/subgraph.d.ts +26 -0
- package/dist/src/review/subgraph.js +146 -0
- package/dist/src/review/subgraph.js.map +1 -0
- package/dist/src/review/supplemental-intelligence.d.ts +15 -0
- package/dist/src/review/supplemental-intelligence.js +431 -0
- package/dist/src/review/supplemental-intelligence.js.map +1 -0
- package/dist/src/review/team-damage.d.ts +8 -0
- package/dist/src/review/team-damage.js +180 -0
- package/dist/src/review/team-damage.js.map +1 -0
- package/dist/src/review/telemetry-events.d.ts +72 -0
- package/dist/src/review/telemetry-events.js +573 -0
- package/dist/src/review/telemetry-events.js.map +1 -0
- package/dist/src/review/telemetry.d.ts +86 -0
- package/dist/src/review/telemetry.js +266 -0
- package/dist/src/review/telemetry.js.map +1 -0
- package/dist/src/review/types.d.ts +501 -0
- package/dist/src/review/types.js +2 -0
- package/dist/src/review/types.js.map +1 -0
- package/dist/src/review/vehicle-intelligence.d.ts +3 -0
- package/dist/src/review/vehicle-intelligence.js +148 -0
- package/dist/src/review/vehicle-intelligence.js.map +1 -0
- package/dist/src/schema/query.d.ts +876 -0
- package/dist/src/schema/query.js +185 -0
- package/dist/src/schema/query.js.map +1 -0
- package/dist/src/schema/status.d.ts +66 -0
- package/dist/src/schema/status.js +49 -0
- package/dist/src/schema/status.js.map +1 -0
- package/dist/src/service/pubg-domain-service.d.ts +192 -0
- package/dist/src/service/pubg-domain-service.js +1598 -0
- package/dist/src/service/pubg-domain-service.js.map +1 -0
- package/dist/src/storage/repository-port.d.ts +84 -0
- package/dist/src/storage/repository-port.js +2 -0
- package/dist/src/storage/repository-port.js.map +1 -0
- package/dist/src/storage/sqlite-repository-adapter.d.ts +33 -0
- package/dist/src/storage/sqlite-repository-adapter.js +66 -0
- package/dist/src/storage/sqlite-repository-adapter.js.map +1 -0
- package/dist/src/storage/sqlite-repository.d.ts +73 -0
- package/dist/src/storage/sqlite-repository.js +652 -0
- package/dist/src/storage/sqlite-repository.js.map +1 -0
- package/dist/src/time/selector-resolver.d.ts +34 -0
- package/dist/src/time/selector-resolver.js +364 -0
- package/dist/src/time/selector-resolver.js.map +1 -0
- package/package.json +42 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ChristmasFox / Arthur Xu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
-
#
|
|
1
|
+
# PUBG Domain
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
PUBG 的平台无关 Domain:官方 PUBG API client、SQLite match/Telemetry store、确定性查询/比较、时间边界、review facts、证据引用和一次性迁移所需的数据结构。OpenClaw plugin 只调用这里的显式 service;本包不依赖 OpenClaw、LangBot、Mastra、Telegram、n8n 或任何 HTTP gateway。
|
|
4
|
+
|
|
5
|
+
`config/default-team.json` 是**完全虚构、不具备真实查询能力的 fixture**,不再包含真实 PUBG Account ID。生产插件要求显式的 `PUBG_TEAM_CONFIG_FILE`,从仓库外加载队伍配置;未配置将 fail closed。
|
|
6
|
+
|
|
7
|
+
初始化自己的小队(根据官方昵称解析官方 PUBG Account ID,默认仅写入 Git 忽略的 `.local/`):
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
node scripts/init-pubg-team.mjs --players PlayerOne,PlayerTwo --platform steam --api-key-file .local/pubg-api-key
|
|
11
|
+
node --test scripts/test-init-pubg-team.mjs
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
详见 [Community PUBG Setup](../../docs/COMMUNITY_PUBG_SETUP.md)。API key、WhatsApp pairing 数据、真实队伍 ID 和其他凭据不得进入 Git。旧 Python V2 和 Runtime 只在 Git 历史中保留,不继续维护第二套实现。
|
|
15
|
+
|
|
16
|
+
## Tenant scope and repository ports
|
|
17
|
+
|
|
18
|
+
Query execution requires an explicit `TeamContext` containing the tenant ID,
|
|
19
|
+
team ID, and validated roster. The caller must resolve that scope before
|
|
20
|
+
entering the Domain; missing or mismatched scope fails closed. Public
|
|
21
|
+
authorization remains the application's responsibility.
|
|
22
|
+
|
|
23
|
+
`PubgDomainService` depends on the asynchronous `PubgRepositoryPort`. The
|
|
24
|
+
private OpenClaw adapter wraps its existing SQLite repository in
|
|
25
|
+
`SqlitePubgRepositoryAdapter`, pinned to the configured private scope. Public
|
|
26
|
+
PostgreSQL persistence is a separate adapter in `apps/pubg-saas`; it uses the
|
|
27
|
+
public database and application authorization, independently of private SQLite.
|
|
28
|
+
Both adapters must preserve the same `ToolEnvelope`, evidence, coverage,
|
|
29
|
+
partial/unknown and temporal contracts.
|
|
30
|
+
|
|
31
|
+
`tests/fixtures/shared-edge-cases.json` locks nine independent synthetic stat
|
|
32
|
+
expectations: KD/zero denominator, revives, squad rank, relative 06:00 periods,
|
|
33
|
+
day grouping, no matches, partial/unknown coverage and comparison ratios. Private
|
|
34
|
+
Domain tests run these without PostgreSQL or the public app. The public suite
|
|
35
|
+
then reads the same fixture through both adapters and compares whole deterministic
|
|
36
|
+
results. It also compares team damage/kick/punch/melee, derived evidence and
|
|
37
|
+
parser/feature cache versions, partial unavailable telemetry, successful zero,
|
|
38
|
+
and cache-only reads after reopening each independent store. These are offline
|
|
39
|
+
fixtures, not live independent deployment or restore acceptance.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "example_squad",
|
|
3
|
+
"label": "Demo Squad (fixture only)",
|
|
4
|
+
"platform": "steam",
|
|
5
|
+
"players": [
|
|
6
|
+
{
|
|
7
|
+
"id": "fixture-player-1",
|
|
8
|
+
"name": "DemoPlayer01",
|
|
9
|
+
"aliases": ["demo1"]
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"id": "fixture-player-2",
|
|
13
|
+
"name": "DemoPlayer02",
|
|
14
|
+
"aliases": ["demo2"]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "fixture-player-3",
|
|
18
|
+
"name": "DemoPlayer03",
|
|
19
|
+
"aliases": ["demo3"]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "fixture-player-4",
|
|
23
|
+
"name": "DemoPlayer04",
|
|
24
|
+
"aliases": ["demo4"]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ChickenIndexWeights {
|
|
2
|
+
kd: number;
|
|
3
|
+
avgDamage: number;
|
|
4
|
+
avgKills: number;
|
|
5
|
+
placement: number;
|
|
6
|
+
top10Rate: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const CHICKEN_INDEX_WEIGHTS: Readonly<ChickenIndexWeights>;
|
|
9
|
+
export declare function normalizeChickenIndexWeights(override?: Partial<ChickenIndexWeights>): ChickenIndexWeights;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const CHICKEN_INDEX_WEIGHTS = Object.freeze({
|
|
2
|
+
kd: 0.35,
|
|
3
|
+
avgDamage: 0.3,
|
|
4
|
+
avgKills: 0.2,
|
|
5
|
+
placement: 0.1,
|
|
6
|
+
top10Rate: 0.05,
|
|
7
|
+
});
|
|
8
|
+
export function normalizeChickenIndexWeights(override = {}) {
|
|
9
|
+
const values = {
|
|
10
|
+
kd: Number.isFinite(override.kd) && (override.kd ?? 0) >= 0
|
|
11
|
+
? Number(override.kd)
|
|
12
|
+
: CHICKEN_INDEX_WEIGHTS.kd,
|
|
13
|
+
avgDamage: Number.isFinite(override.avgDamage) && (override.avgDamage ?? 0) >= 0
|
|
14
|
+
? Number(override.avgDamage)
|
|
15
|
+
: CHICKEN_INDEX_WEIGHTS.avgDamage,
|
|
16
|
+
avgKills: Number.isFinite(override.avgKills) && (override.avgKills ?? 0) >= 0
|
|
17
|
+
? Number(override.avgKills)
|
|
18
|
+
: CHICKEN_INDEX_WEIGHTS.avgKills,
|
|
19
|
+
placement: Number.isFinite(override.placement) && (override.placement ?? 0) >= 0
|
|
20
|
+
? Number(override.placement)
|
|
21
|
+
: CHICKEN_INDEX_WEIGHTS.placement,
|
|
22
|
+
top10Rate: Number.isFinite(override.top10Rate) && (override.top10Rate ?? 0) >= 0
|
|
23
|
+
? Number(override.top10Rate)
|
|
24
|
+
: CHICKEN_INDEX_WEIGHTS.top10Rate,
|
|
25
|
+
};
|
|
26
|
+
const total = Object.values(values).reduce((sum, value) => sum + value, 0);
|
|
27
|
+
if (total <= 0)
|
|
28
|
+
return { ...CHICKEN_INDEX_WEIGHTS };
|
|
29
|
+
return {
|
|
30
|
+
kd: values.kd / total,
|
|
31
|
+
avgDamage: values.avgDamage / total,
|
|
32
|
+
avgKills: values.avgKills / total,
|
|
33
|
+
placement: values.placement / total,
|
|
34
|
+
top10Rate: values.top10Rate / total,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=chicken-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chicken-index.js","sourceRoot":"","sources":["../../../src/config/chicken-index.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,qBAAqB,GAAkC,MAAM,CAAC,MAAM,CAAC;IAChF,EAAE,EAAE,IAAI;IACR,SAAS,EAAE,GAAG;IACd,QAAQ,EAAE,GAAG;IACb,SAAS,EAAE,GAAG;IACd,SAAS,EAAE,IAAI;CAChB,CAAC,CAAC;AAEH,MAAM,UAAU,4BAA4B,CAC1C,WAAyC,EAAE;IAE3C,MAAM,MAAM,GAAG;QACb,EAAE,EACA,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;YACrD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrB,CAAC,CAAC,qBAAqB,CAAC,EAAE;QAC9B,SAAS,EACP,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC;YACnE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC5B,CAAC,CAAC,qBAAqB,CAAC,SAAS;QACrC,QAAQ,EACN,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC;YACjE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC3B,CAAC,CAAC,qBAAqB,CAAC,QAAQ;QACpC,SAAS,EACP,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC;YACnE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC5B,CAAC,CAAC,qBAAqB,CAAC,SAAS;QACrC,SAAS,EACP,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC;YACnE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC5B,CAAC,CAAC,qBAAqB,CAAC,SAAS;KACtC,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;IAC3E,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACpD,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,KAAK;QACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,KAAK;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,KAAK;QACnC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,KAAK;KACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface TeamPlayer {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
aliases: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface TeamConfig {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
platform: string;
|
|
10
|
+
players: TeamPlayer[];
|
|
11
|
+
}
|
|
12
|
+
export declare function assertTeamConfig(value: unknown): TeamConfig;
|
|
13
|
+
/** Checked-in data is a test fixture; production should load an external file. */
|
|
14
|
+
export declare const DEFAULT_TEAM: TeamConfig;
|
|
15
|
+
export declare const DEFAULT_TEAM_PLAYER_IDS: string[];
|
|
16
|
+
export interface TeamConfigLoadOptions {
|
|
17
|
+
path?: string;
|
|
18
|
+
environment?: Readonly<Record<string, string | undefined>>;
|
|
19
|
+
required?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function loadTeamConfig(options?: TeamConfigLoadOptions): TeamConfig;
|
|
22
|
+
export declare function playerAliasMap(team?: TeamConfig): Map<string, TeamPlayer>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import defaultTeam from '../../config/default-team.json' with { type: 'json' };
|
|
3
|
+
export function assertTeamConfig(value) {
|
|
4
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
5
|
+
throw new Error('invalid_team_config');
|
|
6
|
+
const candidate = value;
|
|
7
|
+
const players = Array.isArray(candidate.players) ? candidate.players : [];
|
|
8
|
+
if (!candidate.id || !candidate.label || !candidate.platform || players.length === 0)
|
|
9
|
+
throw new Error('invalid_team_config');
|
|
10
|
+
const normalized = players.map((item) => {
|
|
11
|
+
if (!item || typeof item !== 'object' || Array.isArray(item))
|
|
12
|
+
throw new Error('invalid_team_player');
|
|
13
|
+
const player = item;
|
|
14
|
+
const id = String(player.id ?? '').trim();
|
|
15
|
+
const name = String(player.name ?? '').trim();
|
|
16
|
+
const aliases = Array.isArray(player.aliases)
|
|
17
|
+
? player.aliases
|
|
18
|
+
.map(String)
|
|
19
|
+
.map((alias) => alias.trim())
|
|
20
|
+
.filter(Boolean)
|
|
21
|
+
: [];
|
|
22
|
+
if (!id || !name)
|
|
23
|
+
throw new Error('invalid_team_player');
|
|
24
|
+
return { id, name, aliases };
|
|
25
|
+
});
|
|
26
|
+
const ids = new Set();
|
|
27
|
+
for (const player of normalized) {
|
|
28
|
+
if (ids.has(player.id))
|
|
29
|
+
throw new Error('duplicate_team_player');
|
|
30
|
+
ids.add(player.id);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
id: String(candidate.id),
|
|
34
|
+
label: String(candidate.label),
|
|
35
|
+
platform: String(candidate.platform),
|
|
36
|
+
players: normalized,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Checked-in data is a test fixture; production should load an external file. */
|
|
40
|
+
export const DEFAULT_TEAM = assertTeamConfig(defaultTeam);
|
|
41
|
+
export const DEFAULT_TEAM_PLAYER_IDS = DEFAULT_TEAM.players.map((player) => player.id);
|
|
42
|
+
export function loadTeamConfig(options = {}) {
|
|
43
|
+
const environment = options.environment ?? process.env;
|
|
44
|
+
const filePath = options.path ?? environment.PUBG_TEAM_CONFIG_FILE?.trim();
|
|
45
|
+
if (!filePath) {
|
|
46
|
+
if (options.required)
|
|
47
|
+
throw new Error('team_config_file_required');
|
|
48
|
+
return DEFAULT_TEAM;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
return assertTeamConfig(JSON.parse(readFileSync(filePath, 'utf8')));
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error instanceof Error && error.message.startsWith('invalid_'))
|
|
55
|
+
throw error;
|
|
56
|
+
throw new Error('team_config_unreadable:' + filePath, { cause: error });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function playerAliasMap(team = DEFAULT_TEAM) {
|
|
60
|
+
const aliases = new Map();
|
|
61
|
+
for (const player of team.players) {
|
|
62
|
+
aliases.set(player.id.toLowerCase(), player);
|
|
63
|
+
aliases.set(player.name.toLowerCase(), player);
|
|
64
|
+
for (const alias of player.aliases)
|
|
65
|
+
aliases.set(alias.toLowerCase(), player);
|
|
66
|
+
}
|
|
67
|
+
return aliases;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=team.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team.js","sourceRoot":"","sources":["../../../src/config/team.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { CanonicalQuery } from '../schema/query.js';
|
|
2
|
+
import type { ResultSetRecord, SessionContextRecord } from '../data/model.js';
|
|
3
|
+
export interface ContextStore {
|
|
4
|
+
getContext(sessionId: string): Promise<SessionContextRecord | null>;
|
|
5
|
+
setContext(context: SessionContextRecord): Promise<void>;
|
|
6
|
+
getResultSet(sessionId: string, resultSetId: string): Promise<ResultSetRecord | null>;
|
|
7
|
+
setResultSet(result: ResultSetRecord): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare function sessionId(input: {
|
|
10
|
+
platform: string;
|
|
11
|
+
chatId: string;
|
|
12
|
+
userId: string;
|
|
13
|
+
domain?: string;
|
|
14
|
+
}): string;
|
|
15
|
+
export declare function emptyContext(id: string, now?: Date): SessionContextRecord;
|
|
16
|
+
export declare class InMemoryContextStore implements ContextStore {
|
|
17
|
+
private readonly contexts;
|
|
18
|
+
private readonly results;
|
|
19
|
+
getContext(id: string): Promise<SessionContextRecord | null>;
|
|
20
|
+
setContext(value: SessionContextRecord): Promise<void>;
|
|
21
|
+
getResultSet(session: string, id: string): Promise<ResultSetRecord | null>;
|
|
22
|
+
setResultSet(value: ResultSetRecord): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export declare class JsonContextStore implements ContextStore {
|
|
25
|
+
private readonly filePath;
|
|
26
|
+
private queue;
|
|
27
|
+
constructor(filePath: string);
|
|
28
|
+
private read;
|
|
29
|
+
private write;
|
|
30
|
+
getContext(id: string): Promise<SessionContextRecord | null>;
|
|
31
|
+
setContext(value: SessionContextRecord): Promise<void>;
|
|
32
|
+
getResultSet(session: string, id: string): Promise<ResultSetRecord | null>;
|
|
33
|
+
setResultSet(value: ResultSetRecord): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export declare function contextForQuery(query: CanonicalQuery, resultSetId: string, sessionIdValue: string, ttlMs?: number): SessionContextRecord;
|
|
36
|
+
export declare function withSessionId(query: CanonicalQuery, id: string): CanonicalQuery & {
|
|
37
|
+
reference: CanonicalQuery['reference'] & {
|
|
38
|
+
sessionId: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
function validUntil(value) {
|
|
4
|
+
const timestamp = Date.parse(value);
|
|
5
|
+
return Number.isFinite(timestamp) && timestamp > Date.now();
|
|
6
|
+
}
|
|
7
|
+
export function sessionId(input) {
|
|
8
|
+
return [input.platform, input.chatId, input.userId, input.domain ?? 'pubg']
|
|
9
|
+
.map((part) => encodeURIComponent(String(part || 'unknown')))
|
|
10
|
+
.join(':');
|
|
11
|
+
}
|
|
12
|
+
export function emptyContext(id, now = new Date()) {
|
|
13
|
+
return {
|
|
14
|
+
schemaVersion: 3,
|
|
15
|
+
sessionId: id,
|
|
16
|
+
activeDomain: null,
|
|
17
|
+
lastQuery: null,
|
|
18
|
+
lastSelector: null,
|
|
19
|
+
lastResultSetId: null,
|
|
20
|
+
lastSubject: null,
|
|
21
|
+
references: {},
|
|
22
|
+
activeMatchId: null,
|
|
23
|
+
activeMatchOrdinal: null,
|
|
24
|
+
activeReviewResultSetId: null,
|
|
25
|
+
sourceMatchResultSetId: null,
|
|
26
|
+
updatedAt: now.toISOString(),
|
|
27
|
+
expiresAt: new Date(now.getTime() + 12 * 60 * 60 * 1000).toISOString(),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export class InMemoryContextStore {
|
|
31
|
+
contexts = new Map();
|
|
32
|
+
results = new Map();
|
|
33
|
+
async getContext(id) {
|
|
34
|
+
const value = this.contexts.get(id);
|
|
35
|
+
return value && validUntil(value.expiresAt) ? structuredClone(value) : null;
|
|
36
|
+
}
|
|
37
|
+
async setContext(value) {
|
|
38
|
+
this.contexts.set(value.sessionId, structuredClone(value));
|
|
39
|
+
}
|
|
40
|
+
async getResultSet(session, id) {
|
|
41
|
+
const value = this.results.get(session + ':' + id);
|
|
42
|
+
return value && validUntil(value.expiresAt) ? structuredClone(value) : null;
|
|
43
|
+
}
|
|
44
|
+
async setResultSet(value) {
|
|
45
|
+
this.results.set(value.sessionId + ':' + value.id, structuredClone(value));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export class JsonContextStore {
|
|
49
|
+
filePath;
|
|
50
|
+
queue = Promise.resolve();
|
|
51
|
+
constructor(filePath) {
|
|
52
|
+
this.filePath = filePath;
|
|
53
|
+
}
|
|
54
|
+
async read() {
|
|
55
|
+
try {
|
|
56
|
+
const value = JSON.parse(await fs.readFile(this.filePath, 'utf8'));
|
|
57
|
+
return { contexts: value.contexts ?? {}, results: value.results ?? {} };
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error.code !== 'ENOENT')
|
|
61
|
+
throw error;
|
|
62
|
+
return { contexts: {}, results: {} };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async write(mutator) {
|
|
66
|
+
this.queue = this.queue
|
|
67
|
+
.catch(() => undefined)
|
|
68
|
+
.then(async () => {
|
|
69
|
+
const state = await this.read();
|
|
70
|
+
mutator(state);
|
|
71
|
+
await fs.mkdir(path.dirname(this.filePath), { recursive: true });
|
|
72
|
+
const temporaryPath = this.filePath + '.tmp';
|
|
73
|
+
await fs.writeFile(temporaryPath, JSON.stringify(state), { mode: 0o600 });
|
|
74
|
+
await fs.rename(temporaryPath, this.filePath);
|
|
75
|
+
});
|
|
76
|
+
return this.queue;
|
|
77
|
+
}
|
|
78
|
+
async getContext(id) {
|
|
79
|
+
const state = await this.read();
|
|
80
|
+
const value = state.contexts[id];
|
|
81
|
+
return value && validUntil(value.expiresAt) ? structuredClone(value) : null;
|
|
82
|
+
}
|
|
83
|
+
async setContext(value) {
|
|
84
|
+
await this.write((state) => {
|
|
85
|
+
state.contexts[value.sessionId] = value;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async getResultSet(session, id) {
|
|
89
|
+
const state = await this.read();
|
|
90
|
+
const value = state.results[session + ':' + id];
|
|
91
|
+
return value && validUntil(value.expiresAt) ? value : null;
|
|
92
|
+
}
|
|
93
|
+
async setResultSet(value) {
|
|
94
|
+
await this.write((state) => {
|
|
95
|
+
state.results[value.sessionId + ':' + value.id] = value;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function contextForQuery(query, resultSetId, sessionIdValue, ttlMs = 12 * 60 * 60 * 1000) {
|
|
100
|
+
const now = new Date();
|
|
101
|
+
return {
|
|
102
|
+
schemaVersion: 3,
|
|
103
|
+
sessionId: sessionIdValue,
|
|
104
|
+
activeDomain: 'pubg',
|
|
105
|
+
lastQuery: query,
|
|
106
|
+
lastSelector: query.selector,
|
|
107
|
+
lastResultSetId: resultSetId,
|
|
108
|
+
lastSubject: query.subject,
|
|
109
|
+
references: {
|
|
110
|
+
selectorSource: query.reference.selectorExplicit ? 'tool_input' : 'default',
|
|
111
|
+
},
|
|
112
|
+
updatedAt: now.toISOString(),
|
|
113
|
+
expiresAt: new Date(now.getTime() + ttlMs).toISOString(),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function withSessionId(query, id) {
|
|
117
|
+
return { ...query, reference: { ...query.reference, sessionId: id } };
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=context-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-store.js","sourceRoot":"","sources":["../../../src/context/context-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TeamConfig } from '../config/team.js';
|
|
2
|
+
/**
|
|
3
|
+
* Trusted scope resolved by the calling application before entering PUBG
|
|
4
|
+
* Domain. Public callers must derive it from verified platform event data and
|
|
5
|
+
* persisted ownership; model/tool arguments are never a source for this value.
|
|
6
|
+
*/
|
|
7
|
+
export interface TeamContext {
|
|
8
|
+
tenantId: string;
|
|
9
|
+
teamId: string;
|
|
10
|
+
team: TeamConfig;
|
|
11
|
+
}
|
|
12
|
+
export declare function parseTeamContext(value: unknown): TeamContext;
|
|
13
|
+
export declare function createTeamContext(tenantId: string, team: TeamConfig): TeamContext;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { assertTeamConfig } from '../config/team.js';
|
|
2
|
+
export function parseTeamContext(value) {
|
|
3
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
4
|
+
throw new Error('invalid_team_context');
|
|
5
|
+
const candidate = value;
|
|
6
|
+
const tenantId = typeof candidate.tenantId === 'string' ? candidate.tenantId.trim() : '';
|
|
7
|
+
const teamId = typeof candidate.teamId === 'string' ? candidate.teamId.trim() : '';
|
|
8
|
+
const team = assertTeamConfig(candidate.team);
|
|
9
|
+
if (!tenantId || !teamId || teamId !== team.id)
|
|
10
|
+
throw new Error('invalid_team_context');
|
|
11
|
+
return { tenantId, teamId, team };
|
|
12
|
+
}
|
|
13
|
+
export function createTeamContext(tenantId, team) {
|
|
14
|
+
return parseTeamContext({ tenantId, teamId: team.id, team });
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=team-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-context.js","sourceRoot":"","sources":["../../../src/context/team-context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAarD,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,KAAgC,CAAC;IACnD,MAAM,QAAQ,GAAG,OAAO,SAAS,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzF,MAAM,MAAM,GAAG,OAAO,SAAS,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,IAAgB;IAClE,OAAO,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Platform-neutral PUBG domain entry for runtimes that provide their own
|
|
2
|
+
* repository. Keep private SQLite and legacy import tools on the package root. */
|
|
3
|
+
export * from './config/chicken-index.js';
|
|
4
|
+
export * from './config/team.js';
|
|
5
|
+
export * from './context/context-store.js';
|
|
6
|
+
export * from './context/team-context.js';
|
|
7
|
+
export * from './data/model.js';
|
|
8
|
+
export * from './data/pubg-api-client.js';
|
|
9
|
+
export * from './engine/query-engine.js';
|
|
10
|
+
export * from './review/types.js';
|
|
11
|
+
export * from './review/telemetry-events.js';
|
|
12
|
+
export * from './review/telemetry.js';
|
|
13
|
+
export * from './review/review-facts.js';
|
|
14
|
+
export * from './review/review-analyzer.js';
|
|
15
|
+
export * from './review/fun-candidate-generator.js';
|
|
16
|
+
export * from './review/fun-intelligence.js';
|
|
17
|
+
export * from './review/supplemental-intelligence.js';
|
|
18
|
+
export * from './review/subgraph.js';
|
|
19
|
+
export * from './schema/query.js';
|
|
20
|
+
export * from './schema/status.js';
|
|
21
|
+
export * from './service/pubg-domain-service.js';
|
|
22
|
+
export * from './storage/repository-port.js';
|
|
23
|
+
export * from './time/selector-resolver.js';
|
package/dist/src/core.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Platform-neutral PUBG domain entry for runtimes that provide their own
|
|
2
|
+
* repository. Keep private SQLite and legacy import tools on the package root. */
|
|
3
|
+
export * from './config/chicken-index.js';
|
|
4
|
+
export * from './config/team.js';
|
|
5
|
+
export * from './context/context-store.js';
|
|
6
|
+
export * from './context/team-context.js';
|
|
7
|
+
export * from './data/model.js';
|
|
8
|
+
export * from './data/pubg-api-client.js';
|
|
9
|
+
export * from './engine/query-engine.js';
|
|
10
|
+
export * from './review/types.js';
|
|
11
|
+
export * from './review/telemetry-events.js';
|
|
12
|
+
export * from './review/telemetry.js';
|
|
13
|
+
export * from './review/review-facts.js';
|
|
14
|
+
export * from './review/review-analyzer.js';
|
|
15
|
+
export * from './review/fun-candidate-generator.js';
|
|
16
|
+
export * from './review/fun-intelligence.js';
|
|
17
|
+
export * from './review/supplemental-intelligence.js';
|
|
18
|
+
export * from './review/subgraph.js';
|
|
19
|
+
export * from './schema/query.js';
|
|
20
|
+
export * from './schema/status.js';
|
|
21
|
+
export * from './service/pubg-domain-service.js';
|
|
22
|
+
export * from './storage/repository-port.js';
|
|
23
|
+
export * from './time/selector-resolver.js';
|
|
24
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"AAAA;kFACkF;AAClF,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { Coverage, DataStatus, Evidence, SourceInfo } from '../schema/status.js';
|
|
2
|
+
import type { CanonicalQuery, Metric, Selector } from '../schema/query.js';
|
|
3
|
+
import type { MatchPickerModel, MatchReviewResult } from '../review/types.js';
|
|
4
|
+
export interface NormalizedPlayer {
|
|
5
|
+
accountId: string;
|
|
6
|
+
playerName: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
rank: number | null;
|
|
9
|
+
kills: number;
|
|
10
|
+
assists: number;
|
|
11
|
+
damage: number;
|
|
12
|
+
dbnos: number;
|
|
13
|
+
revives: number;
|
|
14
|
+
headshotKills: number;
|
|
15
|
+
survivalTime: number;
|
|
16
|
+
longestKill: number;
|
|
17
|
+
deaths: number | null;
|
|
18
|
+
deathSemantics: 'explicit' | 'placement_proxy' | 'unknown';
|
|
19
|
+
}
|
|
20
|
+
export interface NormalizedMatch {
|
|
21
|
+
schemaVersion: number;
|
|
22
|
+
matchId: string;
|
|
23
|
+
shard: string;
|
|
24
|
+
createdAt: string | null;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
matchType: string;
|
|
27
|
+
gameMode: string;
|
|
28
|
+
isCompetitive: boolean;
|
|
29
|
+
mapName: string;
|
|
30
|
+
duration: number;
|
|
31
|
+
patchVersion: string;
|
|
32
|
+
players: NormalizedPlayer[];
|
|
33
|
+
telemetryUrl?: string | null;
|
|
34
|
+
}
|
|
35
|
+
export interface DataLayerResult {
|
|
36
|
+
records: NormalizedMatch[];
|
|
37
|
+
coverage: Coverage;
|
|
38
|
+
source: SourceInfo;
|
|
39
|
+
diagnostics?: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
export interface QueryRow {
|
|
42
|
+
key: string;
|
|
43
|
+
label: string;
|
|
44
|
+
groupBy: 'player' | 'match' | 'day' | 'map' | 'mode' | 'team';
|
|
45
|
+
metrics: Record<string, number | null | string>;
|
|
46
|
+
matchId?: string;
|
|
47
|
+
timestamp?: number | null;
|
|
48
|
+
createdAt?: string | null;
|
|
49
|
+
mapName?: string;
|
|
50
|
+
gameMode?: string;
|
|
51
|
+
duration?: number;
|
|
52
|
+
players?: NormalizedPlayer[];
|
|
53
|
+
activityStatus?: 'ACTIVE' | 'NO_ACTIVITY';
|
|
54
|
+
bestRank?: number | null;
|
|
55
|
+
position?: number;
|
|
56
|
+
tied?: boolean;
|
|
57
|
+
comparisonRatios?: Record<string, number | null>;
|
|
58
|
+
}
|
|
59
|
+
export interface OperationData {
|
|
60
|
+
operation: CanonicalQuery['operation'];
|
|
61
|
+
groupBy: CanonicalQuery['groupBy'];
|
|
62
|
+
metric?: Metric;
|
|
63
|
+
direction?: 'asc' | 'desc';
|
|
64
|
+
rows: QueryRow[];
|
|
65
|
+
summary: Record<string, unknown>;
|
|
66
|
+
segments?: Array<{
|
|
67
|
+
label: string;
|
|
68
|
+
selector: Selector;
|
|
69
|
+
rows: QueryRow[];
|
|
70
|
+
summary: Record<string, unknown>;
|
|
71
|
+
}>;
|
|
72
|
+
dailySeries?: QueryRow[];
|
|
73
|
+
change?: Record<string, unknown>;
|
|
74
|
+
highlights?: Record<string, QueryRow[]>;
|
|
75
|
+
}
|
|
76
|
+
export interface StructuredResult {
|
|
77
|
+
queryId: string;
|
|
78
|
+
sessionId: string;
|
|
79
|
+
status: DataStatus;
|
|
80
|
+
data: OperationData;
|
|
81
|
+
coverage: Coverage;
|
|
82
|
+
source: SourceInfo;
|
|
83
|
+
evidence: Evidence;
|
|
84
|
+
resultSetId?: string;
|
|
85
|
+
diagnostics: Record<string, unknown>;
|
|
86
|
+
review?: MatchReviewResult;
|
|
87
|
+
matchPicker?: MatchPickerModel;
|
|
88
|
+
}
|
|
89
|
+
export interface ResultSetRecord {
|
|
90
|
+
id: string;
|
|
91
|
+
queryId: string;
|
|
92
|
+
sessionId: string;
|
|
93
|
+
resolvedQuery: CanonicalQuery;
|
|
94
|
+
resolvedSelector: Selector;
|
|
95
|
+
playerIds: string[];
|
|
96
|
+
matchIds: string[];
|
|
97
|
+
rows: QueryRow[];
|
|
98
|
+
aggregates: Record<string, unknown>;
|
|
99
|
+
rankings: QueryRow[];
|
|
100
|
+
coverage: Coverage;
|
|
101
|
+
status: DataStatus;
|
|
102
|
+
source: SourceInfo;
|
|
103
|
+
createdAt: string;
|
|
104
|
+
expiresAt: string;
|
|
105
|
+
}
|
|
106
|
+
export interface SessionContextRecord {
|
|
107
|
+
schemaVersion: 3;
|
|
108
|
+
sessionId: string;
|
|
109
|
+
activeDomain: 'pubg' | 'homehub' | null;
|
|
110
|
+
lastQuery: CanonicalQuery | null;
|
|
111
|
+
lastSelector: Selector | null;
|
|
112
|
+
lastResultSetId: string | null;
|
|
113
|
+
lastSubject: CanonicalQuery['subject'] | null;
|
|
114
|
+
references: Record<string, unknown>;
|
|
115
|
+
activeMatchId?: string | null;
|
|
116
|
+
activeMatchOrdinal?: number | null;
|
|
117
|
+
activeReviewResultSetId?: string | null;
|
|
118
|
+
sourceMatchResultSetId?: string | null;
|
|
119
|
+
updatedAt: string;
|
|
120
|
+
expiresAt: string;
|
|
121
|
+
}
|
|
122
|
+
export declare function numberOr(value: unknown, fallback?: number): number;
|
|
123
|
+
export declare function normalizeRecords(records: unknown[]): NormalizedMatch[];
|