@crowdedkingdoms/crowdyjs 8.2.0 → 8.3.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.
Files changed (102) hide show
  1. package/README.md +21 -3
  2. package/dist/crowdy-client.d.ts.map +1 -1
  3. package/dist/crowdy-client.js +5 -1
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -2
  7. package/dist/kit/blueprints/combat.d.ts +75 -0
  8. package/dist/kit/blueprints/combat.d.ts.map +1 -0
  9. package/dist/kit/blueprints/combat.js +351 -0
  10. package/dist/kit/blueprints/core.d.ts +222 -0
  11. package/dist/kit/blueprints/core.d.ts.map +1 -0
  12. package/dist/kit/blueprints/core.js +185 -0
  13. package/dist/kit/blueprints/decks.d.ts +50 -0
  14. package/dist/kit/blueprints/decks.d.ts.map +1 -0
  15. package/dist/kit/blueprints/decks.js +163 -0
  16. package/dist/kit/blueprints/economy.d.ts +88 -0
  17. package/dist/kit/blueprints/economy.d.ts.map +1 -0
  18. package/dist/kit/blueprints/economy.js +533 -0
  19. package/dist/kit/blueprints/guild.d.ts +51 -0
  20. package/dist/kit/blueprints/guild.d.ts.map +1 -0
  21. package/dist/kit/blueprints/guild.js +50 -0
  22. package/dist/kit/blueprints/index.d.ts +21 -0
  23. package/dist/kit/blueprints/index.d.ts.map +1 -0
  24. package/dist/kit/blueprints/index.js +20 -0
  25. package/dist/kit/blueprints/inventory.d.ts +38 -0
  26. package/dist/kit/blueprints/inventory.d.ts.map +1 -0
  27. package/dist/kit/blueprints/inventory.js +157 -0
  28. package/dist/kit/blueprints/leaderboards.d.ts +49 -0
  29. package/dist/kit/blueprints/leaderboards.d.ts.map +1 -0
  30. package/dist/kit/blueprints/leaderboards.js +126 -0
  31. package/dist/kit/blueprints/locks.d.ts +82 -0
  32. package/dist/kit/blueprints/locks.d.ts.map +1 -0
  33. package/dist/kit/blueprints/locks.js +155 -0
  34. package/dist/kit/blueprints/loot.d.ts +84 -0
  35. package/dist/kit/blueprints/loot.d.ts.map +1 -0
  36. package/dist/kit/blueprints/loot.js +228 -0
  37. package/dist/kit/blueprints/matches.d.ts +59 -0
  38. package/dist/kit/blueprints/matches.d.ts.map +1 -0
  39. package/dist/kit/blueprints/matches.js +246 -0
  40. package/dist/kit/blueprints/npcs.d.ts +71 -0
  41. package/dist/kit/blueprints/npcs.d.ts.map +1 -0
  42. package/dist/kit/blueprints/npcs.js +122 -0
  43. package/dist/kit/blueprints/plots.d.ts +54 -0
  44. package/dist/kit/blueprints/plots.d.ts.map +1 -0
  45. package/dist/kit/blueprints/plots.js +146 -0
  46. package/dist/kit/blueprints/progression.d.ts +68 -0
  47. package/dist/kit/blueprints/progression.d.ts.map +1 -0
  48. package/dist/kit/blueprints/progression.js +324 -0
  49. package/dist/kit/blueprints/quests.d.ts +65 -0
  50. package/dist/kit/blueprints/quests.d.ts.map +1 -0
  51. package/dist/kit/blueprints/quests.js +284 -0
  52. package/dist/kit/blueprints/worldsim.d.ts +84 -0
  53. package/dist/kit/blueprints/worldsim.d.ts.map +1 -0
  54. package/dist/kit/blueprints/worldsim.js +461 -0
  55. package/dist/kit/combat.d.ts +103 -0
  56. package/dist/kit/combat.d.ts.map +1 -0
  57. package/dist/kit/combat.js +151 -0
  58. package/dist/kit/decks.d.ts +123 -0
  59. package/dist/kit/decks.d.ts.map +1 -0
  60. package/dist/kit/decks.js +138 -0
  61. package/dist/kit/economy.d.ts +244 -0
  62. package/dist/kit/economy.d.ts.map +1 -0
  63. package/dist/kit/economy.js +365 -0
  64. package/dist/kit/features.d.ts +60 -0
  65. package/dist/kit/features.d.ts.map +1 -0
  66. package/dist/kit/features.js +65 -0
  67. package/dist/kit/index.d.ts +13 -2
  68. package/dist/kit/index.d.ts.map +1 -1
  69. package/dist/kit/index.js +12 -1
  70. package/dist/kit/inventory.d.ts +5 -0
  71. package/dist/kit/inventory.d.ts.map +1 -1
  72. package/dist/kit/inventory.js +14 -1
  73. package/dist/kit/kit.d.ts +58 -2
  74. package/dist/kit/kit.d.ts.map +1 -1
  75. package/dist/kit/kit.js +24 -2
  76. package/dist/kit/leaderboards.d.ts +66 -0
  77. package/dist/kit/leaderboards.d.ts.map +1 -0
  78. package/dist/kit/leaderboards.js +94 -0
  79. package/dist/kit/loot.d.ts +106 -0
  80. package/dist/kit/loot.d.ts.map +1 -0
  81. package/dist/kit/loot.js +120 -0
  82. package/dist/kit/matches.d.ts +140 -0
  83. package/dist/kit/matches.d.ts.map +1 -0
  84. package/dist/kit/matches.js +253 -0
  85. package/dist/kit/objects.js +1 -1
  86. package/dist/kit/plots.js +1 -1
  87. package/dist/kit/progression.d.ts +181 -0
  88. package/dist/kit/progression.d.ts.map +1 -0
  89. package/dist/kit/progression.js +265 -0
  90. package/dist/kit/quests.d.ts +110 -0
  91. package/dist/kit/quests.d.ts.map +1 -0
  92. package/dist/kit/quests.js +158 -0
  93. package/dist/kit/social.d.ts +267 -0
  94. package/dist/kit/social.d.ts.map +1 -0
  95. package/dist/kit/social.js +230 -0
  96. package/dist/kit/worldsim.d.ts +225 -0
  97. package/dist/kit/worldsim.d.ts.map +1 -0
  98. package/dist/kit/worldsim.js +231 -0
  99. package/package.json +1 -1
  100. package/dist/kit/blueprints.d.ts +0 -370
  101. package/dist/kit/blueprints.d.ts.map +0 -1
  102. package/dist/kit/blueprints.js +0 -643
@@ -0,0 +1,222 @@
1
+ import type { Scalars, SeedContainerInput, SeedContainerTypeInput, SeedEdgeInput, SeedFunctionInput, SeedGameModelInput, SeedPropertyDefInput, UpsertAutomationInput, UpsertAutomationTriggerInput } from '../../generated/graphql.js';
2
+ /**
3
+ * A composable invoke-policy rule tree, mirroring the server's authority
4
+ * rules (see the Game API "Game Models → Authority" guide). Serialized with
5
+ * {@link kitPolicyJson} into the `invokePolicyJson` a function carries.
6
+ */
7
+ export type KitInvokePolicy = {
8
+ type: 'allow';
9
+ } | {
10
+ type: 'owner_of_self';
11
+ } | {
12
+ type: 'is_host';
13
+ } | {
14
+ type: 'is_current_turn';
15
+ } | {
16
+ type: 'is_participant';
17
+ } | {
18
+ type: 'is_automation';
19
+ } | {
20
+ type: 'tier_feature';
21
+ feature: string;
22
+ } | {
23
+ type: 'group_permission';
24
+ groupId: string;
25
+ permission?: string;
26
+ } | {
27
+ type: 'grid_permission';
28
+ key: string;
29
+ gridId?: string;
30
+ } | {
31
+ type: 'condition';
32
+ expression: string;
33
+ } | {
34
+ type: 'and';
35
+ rules: KitInvokePolicy[];
36
+ } | {
37
+ type: 'or';
38
+ rules: KitInvokePolicy[];
39
+ } | {
40
+ type: 'not';
41
+ rule: KitInvokePolicy;
42
+ };
43
+ /** Serialize a {@link KitInvokePolicy} tree to the wire `invokePolicyJson`. */
44
+ export declare function kitPolicyJson(policy: KitInvokePolicy): string;
45
+ /**
46
+ * A grid-permission filter inside a selector: gates selves/candidates by
47
+ * whether the USER behind each container has/lacks an unexpired runtime grid
48
+ * permission. Requires a game-api with the permission-read selector support
49
+ * (v0.13.12+).
50
+ */
51
+ export interface SelectorPermissionPredicate {
52
+ /** Where the container's user id comes from: its owner, or a property. */
53
+ userFrom: 'owner' | {
54
+ property: string;
55
+ };
56
+ op: 'has' | 'lacks';
57
+ /** Runtime permission key (e.g. 'access', 'update_voxel_data'). */
58
+ key: string;
59
+ /** Literal grid id, a property holding one, or omitted for "on ANY grid". */
60
+ grid?: number | string | {
61
+ property: string;
62
+ };
63
+ }
64
+ /**
65
+ * Typed automation selector (serialized into `selectorJson` at deploy).
66
+ * Property predicates (`selfWhere`/`where`) filter on model data; permission
67
+ * predicates (`selfPermissionWhere`/`candidatePermissionWhere`) filter on the
68
+ * live grid ACL. Extra fields pass through untouched.
69
+ */
70
+ export interface KitSelectorSpec {
71
+ selfWhere?: Array<{
72
+ key: string;
73
+ op: string;
74
+ value: unknown;
75
+ }>;
76
+ selfPermissionWhere?: SelectorPermissionPredicate[];
77
+ pick?: 'nearest' | 'lowest' | 'highest' | 'random';
78
+ ofType?: string;
79
+ where?: Array<{
80
+ key: string;
81
+ op: string;
82
+ value: unknown;
83
+ }>;
84
+ candidatePermissionWhere?: SelectorPermissionPredicate[];
85
+ by?: 'manhattan' | {
86
+ property: string;
87
+ };
88
+ bindAs?: {
89
+ ref?: string;
90
+ x?: string;
91
+ y?: string;
92
+ approachX?: string;
93
+ approachY?: string;
94
+ approachStop?: number;
95
+ };
96
+ [key: string]: unknown;
97
+ }
98
+ /** An automation spec inside a blueprint (the `appId` is bound at deploy). */
99
+ export type KitAutomationSpec = Omit<UpsertAutomationInput, 'appId'>;
100
+ /** An automation event-trigger spec inside a blueprint. */
101
+ export type KitAutomationTriggerSpec = Omit<UpsertAutomationTriggerInput, 'appId'>;
102
+ /**
103
+ * A **blueprint**: a self-contained, declarative bundle of game-model
104
+ * definitions (container types, property defs, functions), optional seed
105
+ * instances, and optional automations that together implement one game
106
+ * concept (an inventory system, a lockable object, an NPC archetype).
107
+ *
108
+ * Blueprints are plain data — build them with {@link inventoryBlueprint},
109
+ * {@link lockBlueprint}, {@link npcBlueprint}, or by hand — then load them
110
+ * into an app with `client.kit(appId).deploy([...])` (requires the app-admin
111
+ * `manage_apps` permission). Deployment is idempotent: seeding upserts
112
+ * definitions and `upsertAutomation` keys on the automation name.
113
+ */
114
+ export interface KitBlueprint {
115
+ /** A short identifier used in error messages (e.g. `'inventory'`). */
116
+ name: string;
117
+ containerTypes?: SeedContainerTypeInput[];
118
+ propertyDefinitions?: SeedPropertyDefInput[];
119
+ functions?: SeedFunctionInput[];
120
+ /** Optional shared/world containers to seed (catalog data, world objects). */
121
+ containers?: SeedContainerInput[];
122
+ /** Optional edges between seeded containers (by `tempId`). */
123
+ edges?: SeedEdgeInput[];
124
+ /** Server-driven automations to upsert after the seed. */
125
+ automations?: KitAutomationSpec[];
126
+ /** Event triggers to attach to the automations. */
127
+ automationTriggers?: KitAutomationTriggerSpec[];
128
+ }
129
+ /** Convert `PascalCase`/`camelCase` to `snake_case` for derived names. */
130
+ export declare function toSnakeCase(name: string): string;
131
+ /** The wire payloads {@link mergeBlueprints} produces for one deployment. */
132
+ export interface MergedBlueprints {
133
+ seedInput: SeedGameModelInput;
134
+ automations: UpsertAutomationInput[];
135
+ automationTriggers: UpsertAutomationTriggerInput[];
136
+ }
137
+ /**
138
+ * Merge blueprints into a single `gameModelSeed` payload plus the automation
139
+ * upserts, rejecting duplicate type, property, function, or automation names
140
+ * across blueprints (a duplicate almost always means two blueprints need
141
+ * distinct prefixes/type names).
142
+ */
143
+ export declare function mergeBlueprints(appId: Scalars['BigInt']['input'], blueprints: KitBlueprint[], options?: {
144
+ sessionId?: string;
145
+ }): MergedBlueprints;
146
+ /**
147
+ * Concatenate several blueprints into ONE composite blueprint (a plain
148
+ * client-side merge of the definition arrays — no collision checks; those
149
+ * happen in {@link mergeBlueprints} at deploy). Used by composite builders
150
+ * such as `guildBlueprint` that bundle other builders' output under a single
151
+ * name.
152
+ */
153
+ export declare function composeBlueprints(name: string, blueprints: KitBlueprint[]): KitBlueprint;
154
+ /**
155
+ * Who may call a **trusted** mutation (XP grants, score submits, loot rolls,
156
+ * currency mints, …) — the kit-standard authority shape mirroring
157
+ * `LockAuthority` (Part of the anti-cheat conventions: reward-granting
158
+ * functions must never be plain player calls):
159
+ *
160
+ * - `'server'` — `invokeScope: "server"`: only app admins may invoke (run it
161
+ * from trusted studio/backend code holding `manage_apps`).
162
+ * - `'host'` — `is_host` policy: the elected host client may invoke.
163
+ * - `'automation'` — `autonomousInvocable` + `is_automation` policy: only
164
+ * server-driven automations may invoke.
165
+ * - `'owner'` — `owner_of_self`: the owning player (only safe for
166
+ * self-limiting functions guarded by conditions).
167
+ * - `{ custom: rule }` — any hand-written policy rule.
168
+ */
169
+ export type KitTrustedAuthority = 'server' | 'host' | 'automation' | 'owner' | {
170
+ custom: KitInvokePolicy;
171
+ };
172
+ /**
173
+ * The function-level fields a {@link KitTrustedAuthority} compiles to.
174
+ * `extraCondition` (when given) is AND'ed into the policy.
175
+ */
176
+ export declare function trustedAuthorityFields(authority: KitTrustedAuthority, extraCondition?: string): Pick<{
177
+ invokePolicyJson: string;
178
+ invokeScope?: string;
179
+ autonomousInvocable?: boolean;
180
+ }, 'invokePolicyJson' | 'invokeScope' | 'autonomousInvocable'>;
181
+ /**
182
+ * AND extra policy rules into a base policy (skipping empties) — the
183
+ * composition point for `policyExtra` options such as
184
+ * `plotBlueprint({ buyPolicyExtra: featureGate('land_owner') })`.
185
+ */
186
+ export declare function andPolicies(base: KitInvokePolicy, ...extra: Array<KitInvokePolicy | undefined>): KitInvokePolicy;
187
+ /**
188
+ * A `tier_feature` policy leaf: the caller's access tier must hold `feature`
189
+ * (defined via `kit.features.define` and granted with
190
+ * `kit.features.grantToTier`). Pass it to any builder's `*policyExtra`
191
+ * option to monetization-gate that function.
192
+ */
193
+ export declare function featureGate(feature: string): KitInvokePolicy;
194
+ /**
195
+ * How kit types mirror their owner's user id into an `owner_user_id`
196
+ * property (expressions cannot read container ownership directly).
197
+ * The kit standard is `'int'`; set `'string'` on a builder only when
198
+ * integrating with models that mirrored the owner as a string (e.g. Blocks
199
+ * with Friends) — generated conditions then compare via `to_string(...)`.
200
+ */
201
+ export type KitOwnerIdKind = 'int' | 'string';
202
+ /**
203
+ * Expression fragment asserting that `ownerExpr` (an `owner_user_id`-style
204
+ * property read) equals a user-id expression (usually the injected
205
+ * `$caller_user_id` / `$self_owner_id` system params), honoring
206
+ * {@link KitOwnerIdKind}.
207
+ */
208
+ export declare function ownerEquals(ownerExpr: string, userExpr: string, kind?: KitOwnerIdKind): string;
209
+ /**
210
+ * Expression fragment asserting that `ownerExpr` (an `owner_user_id`-style
211
+ * property read) equals the calling user, honoring {@link KitOwnerIdKind}.
212
+ */
213
+ export declare function ownerEqualsCaller(ownerExpr: string, kind?: KitOwnerIdKind): string;
214
+ /** The `SeedPropertyDefInput` for a kit-standard owner mirror property. */
215
+ export declare function ownerMirrorProperty(containerTypeName: string, kind?: KitOwnerIdKind): {
216
+ containerTypeName: string;
217
+ key: string;
218
+ valueType: string;
219
+ defaultValueJson: string;
220
+ description: string;
221
+ };
222
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/kit/blueprints/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ /** Serialize a {@link KitInvokePolicy} tree to the wire `invokePolicyJson`. */
2
+ export function kitPolicyJson(policy) {
3
+ return JSON.stringify(policy);
4
+ }
5
+ /** Convert `PascalCase`/`camelCase` to `snake_case` for derived names. */
6
+ export function toSnakeCase(name) {
7
+ return name
8
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
9
+ .replace(/[\s-]+/g, '_')
10
+ .toLowerCase();
11
+ }
12
+ /**
13
+ * Merge blueprints into a single `gameModelSeed` payload plus the automation
14
+ * upserts, rejecting duplicate type, property, function, or automation names
15
+ * across blueprints (a duplicate almost always means two blueprints need
16
+ * distinct prefixes/type names).
17
+ */
18
+ export function mergeBlueprints(appId, blueprints, options = {}) {
19
+ const containerTypes = [];
20
+ const propertyDefinitions = [];
21
+ const functions = [];
22
+ const containers = [];
23
+ const edges = [];
24
+ const automations = [];
25
+ const automationTriggers = [];
26
+ const seenTypes = new Map();
27
+ const seenProps = new Map();
28
+ const seenFunctions = new Map();
29
+ const seenAutomations = new Map();
30
+ const seenTempIds = new Map();
31
+ const claim = (seen, key, blueprintName, kind) => {
32
+ const existing = seen.get(key);
33
+ if (existing !== undefined) {
34
+ throw new Error(`Blueprint '${blueprintName}' redefines ${kind} '${key}' already defined by blueprint '${existing}'`);
35
+ }
36
+ seen.set(key, blueprintName);
37
+ };
38
+ for (const blueprint of blueprints) {
39
+ for (const type of blueprint.containerTypes ?? []) {
40
+ claim(seenTypes, type.typeName, blueprint.name, 'container type');
41
+ containerTypes.push(type);
42
+ }
43
+ for (const prop of blueprint.propertyDefinitions ?? []) {
44
+ claim(seenProps, `${prop.containerTypeName}.${prop.key}`, blueprint.name, 'property');
45
+ propertyDefinitions.push(prop);
46
+ }
47
+ for (const fn of blueprint.functions ?? []) {
48
+ claim(seenFunctions, fn.name, blueprint.name, 'function');
49
+ functions.push(fn);
50
+ }
51
+ for (const container of blueprint.containers ?? []) {
52
+ claim(seenTempIds, container.tempId, blueprint.name, 'container tempId');
53
+ containers.push(container);
54
+ }
55
+ edges.push(...(blueprint.edges ?? []));
56
+ for (const automation of blueprint.automations ?? []) {
57
+ claim(seenAutomations, automation.name, blueprint.name, 'automation');
58
+ automations.push({ ...automation, appId });
59
+ }
60
+ for (const trigger of blueprint.automationTriggers ?? []) {
61
+ automationTriggers.push({ ...trigger, appId });
62
+ }
63
+ }
64
+ const seedInput = {
65
+ appId,
66
+ ...(options.sessionId !== undefined ? { sessionId: options.sessionId } : {}),
67
+ ...(containerTypes.length ? { containerTypes } : {}),
68
+ ...(propertyDefinitions.length ? { propertyDefinitions } : {}),
69
+ ...(functions.length ? { functions } : {}),
70
+ ...(containers.length ? { containers } : {}),
71
+ ...(edges.length ? { edges } : {}),
72
+ };
73
+ return { seedInput, automations, automationTriggers };
74
+ }
75
+ /**
76
+ * Concatenate several blueprints into ONE composite blueprint (a plain
77
+ * client-side merge of the definition arrays — no collision checks; those
78
+ * happen in {@link mergeBlueprints} at deploy). Used by composite builders
79
+ * such as `guildBlueprint` that bundle other builders' output under a single
80
+ * name.
81
+ */
82
+ export function composeBlueprints(name, blueprints) {
83
+ const out = { name };
84
+ for (const bp of blueprints) {
85
+ if (bp.containerTypes?.length) {
86
+ out.containerTypes = [...(out.containerTypes ?? []), ...bp.containerTypes];
87
+ }
88
+ if (bp.propertyDefinitions?.length) {
89
+ out.propertyDefinitions = [
90
+ ...(out.propertyDefinitions ?? []),
91
+ ...bp.propertyDefinitions,
92
+ ];
93
+ }
94
+ if (bp.functions?.length) {
95
+ out.functions = [...(out.functions ?? []), ...bp.functions];
96
+ }
97
+ if (bp.containers?.length) {
98
+ out.containers = [...(out.containers ?? []), ...bp.containers];
99
+ }
100
+ if (bp.edges?.length) {
101
+ out.edges = [...(out.edges ?? []), ...bp.edges];
102
+ }
103
+ if (bp.automations?.length) {
104
+ out.automations = [...(out.automations ?? []), ...bp.automations];
105
+ }
106
+ if (bp.automationTriggers?.length) {
107
+ out.automationTriggers = [
108
+ ...(out.automationTriggers ?? []),
109
+ ...bp.automationTriggers,
110
+ ];
111
+ }
112
+ }
113
+ return out;
114
+ }
115
+ /**
116
+ * The function-level fields a {@link KitTrustedAuthority} compiles to.
117
+ * `extraCondition` (when given) is AND'ed into the policy.
118
+ */
119
+ export function trustedAuthorityFields(authority, extraCondition) {
120
+ const rule = authority === 'server'
121
+ ? { type: 'allow' }
122
+ : authority === 'host'
123
+ ? { type: 'is_host' }
124
+ : authority === 'automation'
125
+ ? { type: 'is_automation' }
126
+ : authority === 'owner'
127
+ ? { type: 'owner_of_self' }
128
+ : authority.custom;
129
+ const policy = extraCondition
130
+ ? { type: 'and', rules: [rule, { type: 'condition', expression: extraCondition }] }
131
+ : rule;
132
+ return {
133
+ invokePolicyJson: kitPolicyJson(policy),
134
+ ...(authority === 'server' ? { invokeScope: 'server' } : {}),
135
+ ...(authority === 'automation' ? { autonomousInvocable: true } : {}),
136
+ };
137
+ }
138
+ /**
139
+ * AND extra policy rules into a base policy (skipping empties) — the
140
+ * composition point for `policyExtra` options such as
141
+ * `plotBlueprint({ buyPolicyExtra: featureGate('land_owner') })`.
142
+ */
143
+ export function andPolicies(base, ...extra) {
144
+ const extras = extra.filter((r) => r !== undefined);
145
+ if (extras.length === 0)
146
+ return base;
147
+ return { type: 'and', rules: [base, ...extras] };
148
+ }
149
+ /**
150
+ * A `tier_feature` policy leaf: the caller's access tier must hold `feature`
151
+ * (defined via `kit.features.define` and granted with
152
+ * `kit.features.grantToTier`). Pass it to any builder's `*policyExtra`
153
+ * option to monetization-gate that function.
154
+ */
155
+ export function featureGate(feature) {
156
+ return { type: 'tier_feature', feature };
157
+ }
158
+ /**
159
+ * Expression fragment asserting that `ownerExpr` (an `owner_user_id`-style
160
+ * property read) equals a user-id expression (usually the injected
161
+ * `$caller_user_id` / `$self_owner_id` system params), honoring
162
+ * {@link KitOwnerIdKind}.
163
+ */
164
+ export function ownerEquals(ownerExpr, userExpr, kind = 'int') {
165
+ return kind === 'string'
166
+ ? `${ownerExpr} == to_string(${userExpr})`
167
+ : `${ownerExpr} == ${userExpr}`;
168
+ }
169
+ /**
170
+ * Expression fragment asserting that `ownerExpr` (an `owner_user_id`-style
171
+ * property read) equals the calling user, honoring {@link KitOwnerIdKind}.
172
+ */
173
+ export function ownerEqualsCaller(ownerExpr, kind = 'int') {
174
+ return ownerEquals(ownerExpr, '$caller_user_id', kind);
175
+ }
176
+ /** The `SeedPropertyDefInput` for a kit-standard owner mirror property. */
177
+ export function ownerMirrorProperty(containerTypeName, kind = 'int') {
178
+ return {
179
+ containerTypeName,
180
+ key: 'owner_user_id',
181
+ valueType: kind,
182
+ defaultValueJson: kind === 'string' ? '""' : '0',
183
+ description: "Mirror of the container owner's user id (kit convention: expressions cannot read container ownership).",
184
+ };
185
+ }
@@ -0,0 +1,50 @@
1
+ import { type KitBlueprint, type KitOwnerIdKind } from './core.js';
2
+ /** Options for {@link decksBlueprint}. */
3
+ export interface DecksBlueprintOptions {
4
+ /** Prefix for the type/function names. Defaults to none. */
5
+ typePrefix?: string;
6
+ /**
7
+ * Turn-based mode: adds `is_current_turn` to draw/play/discard, so only
8
+ * the player whose session turn it is may act. Defaults to false.
9
+ */
10
+ turnBased?: boolean;
11
+ /**
12
+ * Fan-out cap of the manual shuffle automation (raise it above your
13
+ * largest deck size). Defaults to 200.
14
+ */
15
+ shuffleMaxTargets?: number;
16
+ /** Owner-mirror typing (see the kit convention). Defaults to `'int'`. */
17
+ ownerIdKind?: KitOwnerIdKind;
18
+ }
19
+ /** Names derived by {@link decksBlueprint} for a given prefix. */
20
+ export interface DecksNames {
21
+ cardDefType: string;
22
+ cardType: string;
23
+ drawFn: string;
24
+ playFn: string;
25
+ discardFn: string;
26
+ assignPositionFn: string;
27
+ shuffleAutomation: string;
28
+ }
29
+ /** Compute the type/function names a decks blueprint (and its runtime helper) uses. */
30
+ export declare function decksNames(typePrefix?: string): DecksNames;
31
+ /**
32
+ * Blueprint for **cards & hidden information**: an admin `CardDef` catalog
33
+ * and session-scoped `CardInstance`s whose `card_id` carries
34
+ * **`visibility: "owner"`** — the two-property hidden-info trick: only the
35
+ * owner's reads include `card_id`, while the public `revealed_card_id` stays
36
+ * empty until the card is played/discarded (the play function copies it in
37
+ * the same transaction). Opponents can see a card EXISTS in your hand, not
38
+ * what it is — enforced by read filtering, not client discipline.
39
+ *
40
+ * Shuffling is honest about the platform: expressions can't index arrays, so
41
+ * decks are ordered by a `position` int dealt by `assign_position`
42
+ * (`rand_int(0, 1000000)` per card) via a **manual, type-fan-out
43
+ * automation** — `kit.decks.shuffle()` runs it (admin), and drawing takes
44
+ * the owner's lowest-position deck card ("top of deck"; the runtime picks
45
+ * it, the server enforces the zone transition and ownership).
46
+ *
47
+ * Runtime counterpart: `client.kit(appId).decks`.
48
+ */
49
+ export declare function decksBlueprint(options?: DecksBlueprintOptions): KitBlueprint;
50
+ //# sourceMappingURL=decks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decks.d.ts","sourceRoot":"","sources":["../../../src/kit/blueprints/decks.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACpB,MAAM,WAAW,CAAC;AAEnB,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,kEAAkE;AAClE,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,UAAU,SAAK,GAAG,UAAU,CAWtD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,YAAY,CAoJhF"}
@@ -0,0 +1,163 @@
1
+ import { kitPolicyJson, ownerMirrorProperty, toSnakeCase, } from './core.js';
2
+ /** Compute the type/function names a decks blueprint (and its runtime helper) uses. */
3
+ export function decksNames(typePrefix = '') {
4
+ const fnPrefix = typePrefix ? `${toSnakeCase(typePrefix)}_` : '';
5
+ return {
6
+ cardDefType: `${typePrefix}CardDef`,
7
+ cardType: `${typePrefix}CardInstance`,
8
+ drawFn: `${fnPrefix}draw_card`,
9
+ playFn: `${fnPrefix}play_card`,
10
+ discardFn: `${fnPrefix}discard_card`,
11
+ assignPositionFn: `${fnPrefix}assign_position`,
12
+ shuffleAutomation: `${fnPrefix.replace(/_/g, '-')}deck-shuffle`,
13
+ };
14
+ }
15
+ /**
16
+ * Blueprint for **cards & hidden information**: an admin `CardDef` catalog
17
+ * and session-scoped `CardInstance`s whose `card_id` carries
18
+ * **`visibility: "owner"`** — the two-property hidden-info trick: only the
19
+ * owner's reads include `card_id`, while the public `revealed_card_id` stays
20
+ * empty until the card is played/discarded (the play function copies it in
21
+ * the same transaction). Opponents can see a card EXISTS in your hand, not
22
+ * what it is — enforced by read filtering, not client discipline.
23
+ *
24
+ * Shuffling is honest about the platform: expressions can't index arrays, so
25
+ * decks are ordered by a `position` int dealt by `assign_position`
26
+ * (`rand_int(0, 1000000)` per card) via a **manual, type-fan-out
27
+ * automation** — `kit.decks.shuffle()` runs it (admin), and drawing takes
28
+ * the owner's lowest-position deck card ("top of deck"; the runtime picks
29
+ * it, the server enforces the zone transition and ownership).
30
+ *
31
+ * Runtime counterpart: `client.kit(appId).decks`.
32
+ */
33
+ export function decksBlueprint(options = {}) {
34
+ const { typePrefix = '', turnBased = false, shuffleMaxTargets = 200, ownerIdKind: kind = 'int', } = options;
35
+ const names = decksNames(typePrefix);
36
+ const playerPolicy = (condition) => {
37
+ const rules = [
38
+ { type: 'owner_of_self' },
39
+ ...(turnBased ? [{ type: 'is_current_turn' }] : []),
40
+ { type: 'condition', expression: condition },
41
+ ];
42
+ return kitPolicyJson({ type: 'and', rules });
43
+ };
44
+ const propertyDefinitions = [
45
+ {
46
+ containerTypeName: names.cardDefType,
47
+ key: 'card_id',
48
+ valueType: 'string',
49
+ description: 'Stable card identifier (rules data lives on the def).',
50
+ },
51
+ ownerMirrorProperty(names.cardType, kind),
52
+ {
53
+ containerTypeName: names.cardType,
54
+ key: 'card_id',
55
+ valueType: 'string',
56
+ defaultValueJson: '""',
57
+ visibility: 'owner',
58
+ description: "WHICH card this is — owner-visible only (the hidden-information half of the two-property trick); opponents' reads omit it.",
59
+ },
60
+ {
61
+ containerTypeName: names.cardType,
62
+ key: 'revealed_card_id',
63
+ valueType: 'string',
64
+ defaultValueJson: '""',
65
+ description: 'The public half: empty while the card hides in deck/hand, copied from card_id when played or discarded.',
66
+ },
67
+ {
68
+ containerTypeName: names.cardType,
69
+ key: 'zone',
70
+ valueType: 'string',
71
+ defaultValueJson: '"deck"',
72
+ description: "Card zone: 'deck' | 'hand' | 'board' | 'discard'.",
73
+ },
74
+ {
75
+ containerTypeName: names.cardType,
76
+ key: 'position',
77
+ valueType: 'int',
78
+ defaultValueJson: '0',
79
+ description: 'Deck order (lowest = top), dealt by the shuffle automation via rand_int.',
80
+ },
81
+ ];
82
+ const functions = [
83
+ {
84
+ name: names.drawFn,
85
+ containerTypeName: names.cardType,
86
+ returnType: 'string',
87
+ mutations: [{ target: 'self', property: 'zone', expression: '"hand"' }],
88
+ returnExpression: 'self.zone',
89
+ invokePolicyJson: playerPolicy('self.zone == "deck"'),
90
+ description: 'Draw a card you own from your deck into your hand (the runtime picks the lowest-position deck card — "top of deck"); card_id stays owner-visible.',
91
+ },
92
+ {
93
+ name: names.playFn,
94
+ containerTypeName: names.cardType,
95
+ returnType: 'string',
96
+ mutations: [
97
+ { target: 'self', property: 'zone', expression: '"board"' },
98
+ { target: 'self', property: 'revealed_card_id', expression: 'self.card_id' },
99
+ ],
100
+ returnExpression: 'self.revealed_card_id',
101
+ invokePolicyJson: playerPolicy('self.zone == "hand"'),
102
+ description: 'Play a card from your hand: the zone flip AND the public reveal (revealed_card_id = card_id) commit together.',
103
+ },
104
+ {
105
+ name: names.discardFn,
106
+ containerTypeName: names.cardType,
107
+ returnType: 'string',
108
+ mutations: [
109
+ { target: 'self', property: 'zone', expression: '"discard"' },
110
+ { target: 'self', property: 'revealed_card_id', expression: 'self.card_id' },
111
+ ],
112
+ returnExpression: 'self.revealed_card_id',
113
+ invokePolicyJson: playerPolicy('self.zone == "hand" || self.zone == "board"'),
114
+ description: 'Discard a card face-up (discard piles are public information).',
115
+ },
116
+ {
117
+ name: names.assignPositionFn,
118
+ containerTypeName: names.cardType,
119
+ returnType: 'int',
120
+ mutations: [
121
+ { target: 'self', property: 'position', expression: 'rand_int(0, 1000000)' },
122
+ ],
123
+ returnExpression: 'self.position',
124
+ invokePolicyJson: kitPolicyJson({ type: 'is_automation' }),
125
+ autonomousInvocable: true,
126
+ description: 'Shuffle step (automation-only): deals this card a random deck position — the supported server-side shuffle pattern (expressions cannot permute arrays).',
127
+ },
128
+ ];
129
+ const automations = [
130
+ {
131
+ name: names.shuffleAutomation,
132
+ functionName: names.assignPositionFn,
133
+ targetMode: 'type',
134
+ targetTypeName: names.cardType,
135
+ triggerType: 'manual',
136
+ maxTargets: shuffleMaxTargets,
137
+ selectorJson: JSON.stringify({
138
+ selfWhere: [{ key: 'zone', op: '==', value: 'deck' }],
139
+ }),
140
+ description: 'Manual shuffle: fans assign_position out over every deck-zone card (run via gameModelRunAutomation / kit.decks.shuffle).',
141
+ },
142
+ ];
143
+ return {
144
+ name: names.cardType,
145
+ containerTypes: [
146
+ {
147
+ typeName: names.cardDefType,
148
+ displayName: names.cardDefType,
149
+ instantiableBy: 'admin',
150
+ description: 'Studio card catalog row.',
151
+ },
152
+ {
153
+ typeName: names.cardType,
154
+ displayName: names.cardType,
155
+ instantiableBy: 'member',
156
+ description: 'One card in play: hidden while in deck/hand (owner-visible card_id), public once revealed.',
157
+ },
158
+ ],
159
+ propertyDefinitions,
160
+ functions,
161
+ automations,
162
+ };
163
+ }