@voltro/plugin-flags 0.85.0 → 0.87.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/CHANGELOG.md +5987 -0
- package/README.md +106 -0
- package/THIRD-PARTY-NOTICES.md +1125 -34
- package/dist/config-inspect.d.ts +33 -0
- package/dist/config-inspect.js +29 -0
- package/dist/config-port.d.ts +247 -0
- package/dist/config-port.js +125 -0
- package/dist/config-testing.d.ts +336 -0
- package/dist/config-testing.js +114 -0
- package/dist/config.d.ts +250 -0
- package/dist/config.js +235 -0
- package/dist/{define-BHpLJh1F.js → define.js} +1 -1
- package/dist/errors.d.ts +18 -0
- package/dist/errors.js +15 -2
- package/dist/evaluate.js +81 -0
- package/dist/experimentLink.js +48 -0
- package/dist/index.d.ts +164 -1
- package/dist/index.js +330 -609
- package/dist/lifecycle.js +82 -0
- package/dist/rpc.d.ts +14 -0
- package/dist/rpc.js +29 -14
- package/dist/store.js +190 -0
- package/dist/usage.js +113 -0
- package/dist/web.d.ts +24 -0
- package/dist/web.js +15 -9
- package/package.json +26 -6
package/README.md
CHANGED
|
@@ -24,3 +24,109 @@ deliberately short so there is nothing here to drift out of date.
|
|
|
24
24
|
|
|
25
25
|
Proprietary. © 2026 Voltro UG. Your use is governed by the
|
|
26
26
|
[Terms of Service](https://voltro.cloud/legal/terms). See the bundled `LICENSE`.
|
|
27
|
+
|
|
28
|
+
## Typed Remote Config
|
|
29
|
+
|
|
30
|
+
`defineConfig` is an optional `flagsPlugin` extension. Its declared bounds are
|
|
31
|
+
budgets. Config editing, automatic Room delivery and a full LiveOps lifecycle
|
|
32
|
+
remain open.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
// lib/public-game-config.ts — browser-safe public declarations only
|
|
36
|
+
import { Schema } from 'effect'
|
|
37
|
+
import { defineConfig } from '@voltro/plugin-flags/config'
|
|
38
|
+
|
|
39
|
+
export const publicConfigSpec = {
|
|
40
|
+
'xp.multiplier': { schema: Schema.Number, default: 1, min: 0.5, max: 5, public: true },
|
|
41
|
+
'shop.featured': { schema: Schema.Array(Schema.String), default: [], public: true, restartRequired: 'live' },
|
|
42
|
+
} as const
|
|
43
|
+
export const publicGameConfig = defineConfig(publicConfigSpec)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// app.config.ts — server only
|
|
48
|
+
import { Schema } from 'effect'
|
|
49
|
+
import { flagsPlugin } from '@voltro/plugin-flags'
|
|
50
|
+
import { defineConfig } from '@voltro/plugin-flags/config'
|
|
51
|
+
import { publicConfigSpec } from './lib/public-game-config'
|
|
52
|
+
|
|
53
|
+
export const gameConfig = defineConfig({
|
|
54
|
+
...publicConfigSpec,
|
|
55
|
+
'arena.maxPlayers': { schema: Schema.Int, default: 32, min: 1, max: 256, restartRequired: 'room' },
|
|
56
|
+
})
|
|
57
|
+
export const plugins = [flagsPlugin({ config: gameConfig, store: 'postgres' })]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`store:'postgres'` names the existing durable Flag tier; it borrows the app
|
|
61
|
+
DataStore and its SQL dialect. No separate pool or Config table is created.
|
|
62
|
+
Validated rows in `_voltro_feature_flags` replace the code definition whole.
|
|
63
|
+
Invalid values, targeting, schedules or bounds refuse the entire override and
|
|
64
|
+
retain the code definition. Error and inspect responses omit rejected values.
|
|
65
|
+
SQL is the override truth and rebuild source; no direct backend or tick read is
|
|
66
|
+
introduced.
|
|
67
|
+
|
|
68
|
+
Each key declares an Effect Schema and a typed default. Numeric `min`/`max`
|
|
69
|
+
refine that schema. `variants`, `targeting`, `rollout`, `rolloutBy` and `schedule`
|
|
70
|
+
reuse Flag targeting and deterministic bucketing. A disabled, excluded or
|
|
71
|
+
out-of-window Config resolves to its declared default. Keys are private by
|
|
72
|
+
default; only `public:true` keys reach the caller-bound `config.mine` query.
|
|
73
|
+
Existing Flag evaluation, variant queries, lifecycle rows and boolean toggles
|
|
74
|
+
omit Config keys. A Config key cannot be edited through the boolean toggle.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
// server handler — read before Room creation, never from its tick
|
|
78
|
+
import { Effect } from 'effect'
|
|
79
|
+
import { ConfigPort, configValue } from '@voltro/plugin-flags/config-port'
|
|
80
|
+
import { gameConfig } from './app.config'
|
|
81
|
+
|
|
82
|
+
export const readRoomConfig = (subject: { id: string; tenantId?: string; type?: string }) =>
|
|
83
|
+
Effect.gen(function* () {
|
|
84
|
+
const config = yield* ConfigPort
|
|
85
|
+
const multiplier = yield* configValue(gameConfig, config, 'xp.multiplier', subject)
|
|
86
|
+
const snapshot = yield* config.snapshot(subject, 'room')
|
|
87
|
+
return { multiplier, snapshot }
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The complete read port is `get(key,subject)`, `mine(subject)` and
|
|
92
|
+
`snapshot(subject,'room'|'live')`. `room` is the default application scope;
|
|
93
|
+
`live` is explicit. A snapshot uses one time and one merged definition set.
|
|
94
|
+
The app passes it during creation or through an explicit message outside the
|
|
95
|
+
tick. Declaring a scope does not install Room delivery. Escaped effects from a
|
|
96
|
+
released activation refuse reads; another Flag instance does not replace this
|
|
97
|
+
instance's Config snapshot.
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { useConfig } from '@voltro/plugin-flags/web'
|
|
101
|
+
import { publicGameConfig } from '../lib/public-game-config'
|
|
102
|
+
|
|
103
|
+
export function FeaturedItems() {
|
|
104
|
+
const items = useConfig(publicGameConfig, 'shop.featured')
|
|
105
|
+
return <ul>{items.map(item => <li key={item}>{item}</li>)}</ul>
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The web hook accepts only explicitly public keys and uses the validated default
|
|
110
|
+
while no valid response exists. Import a browser-safe catalog that contains no
|
|
111
|
+
private values; server-only declarations must stay outside web imports.
|
|
112
|
+
|
|
113
|
+
`configResolver` overrides the pure resolution slot and requires a named
|
|
114
|
+
`configVersion` other than `default.v1`. `configService` replaces all three port
|
|
115
|
+
methods, preserves class receivers and requires the same version plus explicit
|
|
116
|
+
`configQuerySources` (an empty list means an app-owned static view). Resolver and
|
|
117
|
+
complete port replacement cannot be combined. Replacement owns its storage,
|
|
118
|
+
privacy and invalidation sources; it borrows no default persistence behavior.
|
|
119
|
+
Returned keys and values still obey the declared public/snapshot schema.
|
|
120
|
+
|
|
121
|
+
The value and override capture budget is 16,384 encoded JSON bytes, 4,096 nodes,
|
|
122
|
+
16 nesting levels, 1,024 array entries and 256 object properties; keys are bounded
|
|
123
|
+
to 120 characters and catalogs to 128 keys. Override metadata counts toward the
|
|
124
|
+
byte budget too. Non-finite numbers, cycles, accessors, non-JSON objects and
|
|
125
|
+
unbounded input refuse. These are configured limits, not measured capacities.
|
|
126
|
+
Config contributes no new subject table. App-owned replacement privacy remains
|
|
127
|
+
its owner's responsibility; existing Flag audit/usage retention is independent.
|
|
128
|
+
|
|
129
|
+
Local and Cloud Flags panels show key/type/public/scope/bounds/version/ownership
|
|
130
|
+
through the same canonical inspect schema. They never show resolved values,
|
|
131
|
+
subjects or rejected payloads, and distinguish the remaining editor/delivery
|
|
132
|
+
work.
|