@nmnmcc/ability 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.
@@ -1,160 +0,0 @@
1
- import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
- import { fromRawRules, isAbility } from "./Ability.js";
3
- import * as Effect from "effect/Effect";
4
- import * as Equal from "effect/Equal";
5
- import * as Formatter from "effect/Formatter";
6
- import { dual } from "effect/Function";
7
- import * as Hash from "effect/Hash";
8
- import * as Inspectable from "effect/Inspectable";
9
- import * as Pipeable from "effect/Pipeable";
10
- import * as Predicate from "effect/Predicate";
11
- //#region src/AbilityRef.ts
12
- /**
13
- * Mutable ability references for applications that need to swap immutable
14
- * abilities at runtime.
15
- *
16
- * Mental model:
17
- * - `AbilityRef` is the explicit mutable boundary for this package.
18
- * - The current ability can be replaced while subscribers observe update events.
19
- * - All policy evaluation still happens against immutable `Ability` values.
20
- *
21
- * Common tasks:
22
- * - Create a reference with {@link make}.
23
- * - Read the current ability with {@link get}.
24
- * - Replace the current ability with {@link set} or {@link update}.
25
- * - Subscribe to update events with {@link on}.
26
- *
27
- * Gotchas:
28
- * - Event handlers run in registration order.
29
- * - `update` accepts raw rules and reuses the current ability options.
30
- * - `AbilityRef` equality is referential because the current value is mutable.
31
- *
32
- * @since 0.1.0
33
- * @module
34
- */
35
- var AbilityRef_exports = /* @__PURE__ */ __exportAll({
36
- TypeId: () => TypeId,
37
- get: () => get,
38
- isAbilityRef: () => isAbilityRef,
39
- make: () => make,
40
- on: () => on,
41
- set: () => set,
42
- update: () => update
43
- });
44
- /**
45
- * @since 0.1.0
46
- * @category Type Ids
47
- */
48
- const TypeId = Symbol.for("@nmnmcc/ability/AbilityRef");
49
- const RefIdentityTypeId = Symbol.for("@nmnmcc/ability/AbilityRef/identity");
50
- let refIdentity = 0;
51
- const inspectableToString = function() {
52
- return Formatter.format(this.toJSON(), {
53
- ignoreToString: true,
54
- space: 2
55
- });
56
- };
57
- const inspectableNode = function() {
58
- return this.toJSON();
59
- };
60
- const AbilityRefProto = {
61
- ...Pipeable.Prototype,
62
- [TypeId]: TypeId,
63
- [Equal.symbol](that) {
64
- return isAbilityRef(that) && this[RefIdentityTypeId] === that[RefIdentityTypeId];
65
- },
66
- [Hash.symbol]() {
67
- return Hash.number(this[RefIdentityTypeId]);
68
- },
69
- toString: inspectableToString,
70
- toJSON() {
71
- return {
72
- _id: "AbilityRef",
73
- current: this.current
74
- };
75
- },
76
- [Inspectable.NodeInspectSymbol]: inspectableNode
77
- };
78
- /**
79
- * @since 0.1.0
80
- * @category Constructors
81
- */
82
- const make = (ability) => {
83
- const ref = Object.create(AbilityRefProto);
84
- ref.current = ability;
85
- ref[RefIdentityTypeId] = refIdentity;
86
- refIdentity = refIdentity + 1;
87
- ref.handlers = {
88
- update: [],
89
- updated: []
90
- };
91
- return ref;
92
- };
93
- /**
94
- * @since 0.1.0
95
- * @category Guards
96
- */
97
- const isAbilityRef = (value) => Predicate.hasProperty(value, TypeId);
98
- /**
99
- * @since 0.1.0
100
- * @category Accessors
101
- */
102
- const get = (self) => self.current;
103
- const toEffect = (evaluate) => Effect.flatMap(Effect.sync(evaluate), (result) => Effect.isEffect(result) ? result : Effect.void);
104
- const emit = Effect.fnUntraced(function* (self, name, event) {
105
- const handlers = Array.from(self.handlers[name]);
106
- for (const handler of handlers) yield* toEffect(() => handler(event));
107
- });
108
- /**
109
- * @since 0.1.0
110
- * @category Combinators
111
- */
112
- const setEffect = Effect.fnUntraced(function* (self, ability) {
113
- const previous = self.current;
114
- const next = ability;
115
- const mutable = self;
116
- yield* emit(self, "update", {
117
- previous,
118
- next
119
- });
120
- mutable.current = next;
121
- yield* emit(self, "updated", {
122
- previous,
123
- current: next
124
- });
125
- });
126
- /**
127
- * @since 0.1.0
128
- * @category Combinators
129
- */
130
- const set = dual(2, setEffect);
131
- /**
132
- * @since 0.1.0
133
- * @category Combinators
134
- */
135
- const update = dual(2, Effect.fnUntraced(function* (self, next) {
136
- if (Symbol.iterator in Object(next) && !isAbility(next)) return yield* setEffect(self, yield* fromRawRules(next, self.current.options));
137
- return yield* setEffect(self, next);
138
- }));
139
- /**
140
- * @since 0.1.0
141
- * @category Combinators
142
- */
143
- const onEffect = (self, name, handler) => Effect.sync(() => {
144
- const handlers = self.handlers[name];
145
- handlers.push(handler);
146
- let active = true;
147
- return () => {
148
- if (!active) return;
149
- active = false;
150
- const index = handlers.indexOf(handler);
151
- if (index >= 0) handlers.splice(index, 1);
152
- };
153
- });
154
- /**
155
- * @since 0.1.0
156
- * @category Combinators
157
- */
158
- const on = dual(3, onEffect);
159
- //#endregion
160
- export { AbilityRef_exports, TypeId, get, isAbilityRef, make, on, set, update };