@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.
- package/README.md +425 -95
- package/dist/Ability.d.ts +46 -71
- package/dist/Ability.js +12 -16
- package/dist/AbilityExtra.d.ts +3 -3
- package/dist/AbilityExtra.js +0 -8
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/internal/ability.d.ts +1 -25
- package/dist/internal/ability.js +77 -151
- package/package.json +10 -12
- package/dist/AbilityRef.d.ts +0 -110
- package/dist/AbilityRef.js +0 -160
package/dist/AbilityRef.js
DELETED
|
@@ -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 };
|