@nmnmcc/ability 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.
@@ -0,0 +1,211 @@
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import { AliasError as AliasError$1, AuthorizationError as AuthorizationError$1, ConditionError as ConditionError$1, PredicateEvaluationError as PredicateEvaluationError$1, QueryGenerationError as QueryGenerationError$1, RawRuleError as RawRuleError$1, RuleTypeId as RuleTypeId$1, SerializationError as SerializationError$1, SubjectDetectionError as SubjectDetectionError$1, SubjectTypeId as SubjectTypeId$1, TypeId as TypeId$1, actionsFor as actionsFor$1, check as check$1, createAliasResolver as createAliasResolver$1, define as define$1, detectSubjectType as detectSubjectType$1, fromRawRules as fromRawRules$1, isAbility as isAbility$1, isRule as isRule$1, isSubject as isSubject$1, make as make$1, permittedFields as permittedFields$1, possibleRulesFor as possibleRulesFor$1, relevantRuleFor as relevantRuleFor$1, rulesFor as rulesFor$1, subject as subject$1, toRawRules as toRawRules$1, unwrapSubject as unwrapSubject$1 } from "./internal/ability.js";
3
+ //#region src/Ability.ts
4
+ var Ability_exports = /* @__PURE__ */ __exportAll({
5
+ AliasError: () => AliasError,
6
+ AuthorizationError: () => AuthorizationError,
7
+ ConditionError: () => ConditionError,
8
+ PredicateEvaluationError: () => PredicateEvaluationError,
9
+ QueryGenerationError: () => QueryGenerationError,
10
+ RawRuleError: () => RawRuleError,
11
+ RuleTypeId: () => RuleTypeId,
12
+ SerializationError: () => SerializationError,
13
+ SubjectDetectionError: () => SubjectDetectionError,
14
+ SubjectTypeId: () => SubjectTypeId,
15
+ TypeId: () => TypeId,
16
+ actionsFor: () => actionsFor,
17
+ check: () => check,
18
+ createAliasResolver: () => createAliasResolver,
19
+ define: () => define,
20
+ detectSubjectType: () => detectSubjectType,
21
+ fromRawRules: () => fromRawRules,
22
+ isAbility: () => isAbility,
23
+ isRule: () => isRule,
24
+ isSubject: () => isSubject,
25
+ make: () => make,
26
+ permittedFields: () => permittedFields,
27
+ possibleRulesFor: () => possibleRulesFor,
28
+ relevantRuleFor: () => relevantRuleFor,
29
+ rulesFor: () => rulesFor,
30
+ subject: () => subject,
31
+ toRawRules: () => toRawRules,
32
+ unwrapSubject: () => unwrapSubject
33
+ });
34
+ /**
35
+ * @since 0.1.0
36
+ * @category Type Ids
37
+ */
38
+ const TypeId = TypeId$1;
39
+ /**
40
+ * @since 0.1.0
41
+ * @category Type Ids
42
+ */
43
+ const SubjectTypeId = SubjectTypeId$1;
44
+ /**
45
+ * Unique identifier for `Rule` values.
46
+ *
47
+ * @since 0.1.0
48
+ * @category Type Ids
49
+ */
50
+ const RuleTypeId = RuleTypeId$1;
51
+ /**
52
+ * @since 0.1.0
53
+ * @category Errors
54
+ */
55
+ const AuthorizationError = AuthorizationError$1;
56
+ /**
57
+ * @since 0.1.0
58
+ * @category Errors
59
+ */
60
+ const ConditionError = ConditionError$1;
61
+ /**
62
+ * @since 0.1.0
63
+ * @category Errors
64
+ */
65
+ const PredicateEvaluationError = PredicateEvaluationError$1;
66
+ /**
67
+ * @since 0.1.0
68
+ * @category Errors
69
+ */
70
+ const SerializationError = SerializationError$1;
71
+ /**
72
+ * @since 0.1.0
73
+ * @category Errors
74
+ */
75
+ const RawRuleError = RawRuleError$1;
76
+ /**
77
+ * @since 0.1.0
78
+ * @category Errors
79
+ */
80
+ const SubjectDetectionError = SubjectDetectionError$1;
81
+ /**
82
+ * @since 0.1.0
83
+ * @category Errors
84
+ */
85
+ const AliasError = AliasError$1;
86
+ /**
87
+ * @since 0.1.0
88
+ * @category Errors
89
+ */
90
+ const QueryGenerationError = QueryGenerationError$1;
91
+ /**
92
+ * Creates an action resolver for an alias map.
93
+ *
94
+ * @since 0.1.0
95
+ * @category Constructors
96
+ */
97
+ const createAliasResolver = createAliasResolver$1;
98
+ /**
99
+ * Defines an immutable Ability from a generator-based rule program.
100
+ *
101
+ * @since 0.1.0
102
+ * @category Constructors
103
+ */
104
+ const define = define$1;
105
+ /**
106
+ * Constructs an Ability directly from rules.
107
+ *
108
+ * @since 0.1.0
109
+ * @category Constructors
110
+ */
111
+ const make = make$1;
112
+ /**
113
+ * Constructs an Ability from JSON-safe rules.
114
+ *
115
+ * @since 0.1.0
116
+ * @category Constructors
117
+ */
118
+ const fromRawRules = fromRawRules$1;
119
+ /**
120
+ * Creates a pure typed subject wrapper without mutating the wrapped value.
121
+ *
122
+ * @since 0.1.0
123
+ * @category Constructors
124
+ */
125
+ const subject = subject$1;
126
+ /**
127
+ * Returns whether a value is an Ability.
128
+ *
129
+ * @since 0.1.0
130
+ * @category Guards
131
+ */
132
+ const isAbility = isAbility$1;
133
+ /**
134
+ * Returns whether a value is a rule.
135
+ *
136
+ * @since 0.1.0
137
+ * @category Guards
138
+ */
139
+ const isRule = isRule$1;
140
+ /**
141
+ * Returns whether a value is a typed subject wrapper.
142
+ *
143
+ * @since 0.1.0
144
+ * @category Guards
145
+ */
146
+ const isSubject = isSubject$1;
147
+ /**
148
+ * Unwraps a typed subject wrapper.
149
+ *
150
+ * @since 0.1.0
151
+ * @category Accessors
152
+ */
153
+ const unwrapSubject = unwrapSubject$1;
154
+ /**
155
+ * Detects a subject name for a value using an Ability's detection strategy.
156
+ *
157
+ * @since 0.1.0
158
+ * @category Accessors
159
+ */
160
+ const detectSubjectType = detectSubjectType$1;
161
+ /**
162
+ * Converts an Ability to JSON-safe raw rules.
163
+ *
164
+ * @since 0.1.0
165
+ * @category Conversions
166
+ */
167
+ const toRawRules = toRawRules$1;
168
+ /**
169
+ * Returns rules that may apply for a request before field, condition and predicate checks.
170
+ *
171
+ * @since 0.1.0
172
+ * @category Accessors
173
+ */
174
+ const possibleRulesFor = possibleRulesFor$1;
175
+ /**
176
+ * Returns rules that may apply for a request after field checks.
177
+ *
178
+ * @since 0.1.0
179
+ * @category Accessors
180
+ */
181
+ const rulesFor = rulesFor$1;
182
+ /**
183
+ * Returns the first matching rule for a request, if any.
184
+ *
185
+ * @since 0.1.0
186
+ * @category Accessors
187
+ */
188
+ const relevantRuleFor = relevantRuleFor$1;
189
+ /**
190
+ * Returns actions that have rules for a subject.
191
+ *
192
+ * @since 0.1.0
193
+ * @category Accessors
194
+ */
195
+ const actionsFor = actionsFor$1;
196
+ /**
197
+ * Checks a request and fails with `AuthorizationError` when the request is not authorized.
198
+ *
199
+ * @since 0.1.0
200
+ * @category Combinators
201
+ */
202
+ const check = check$1;
203
+ /**
204
+ * Computes fields permitted for a request.
205
+ *
206
+ * @since 0.1.0
207
+ * @category Combinators
208
+ */
209
+ const permittedFields = permittedFields$1;
210
+ //#endregion
211
+ export { Ability_exports, AliasError, AuthorizationError, ConditionError, PredicateEvaluationError, QueryGenerationError, RawRuleError, RuleTypeId, SerializationError, SubjectDetectionError, SubjectTypeId, TypeId, actionsFor, check, createAliasResolver, define, detectSubjectType, fromRawRules, isAbility, isRule, isSubject, make, permittedFields, possibleRulesFor, relevantRuleFor, rulesFor, subject, toRawRules, unwrapSubject };
@@ -0,0 +1,79 @@
1
+ import { Ability, ActionAliases, AnyRule, QueryGenerationError, RawRule, RuleQueryRequest, SubjectDetectionError, SubjectMap } from "./Ability.js";
2
+ import * as Effect from "effect/Effect";
3
+
4
+ //#region src/AbilityExtra.d.ts
5
+ declare namespace AbilityExtra_d_exports {
6
+ export { LogicalQuery, PackRule, RulesToConditionHooks, packRules, rulesToCondition, rulesToFields, rulesToQuery, unpackRules };
7
+ }
8
+ /**
9
+ * @since 0.1.0
10
+ * @category Models
11
+ */
12
+ type PackRule<Rule extends RawRule = RawRule> = readonly [action: Rule["action"], subject: Rule["subject"], conditions?: Rule["conditions"] | 0, inverted?: 1 | 0, fields?: Rule["fields"] | 0, reason?: string];
13
+ /**
14
+ * @since 0.1.0
15
+ * @category Models
16
+ */
17
+ interface RulesToConditionHooks<Query> {
18
+ readonly and: (conditions: ReadonlyArray<Query>) => Query;
19
+ readonly or: (conditions: ReadonlyArray<Query>) => Query;
20
+ readonly not: (condition: Query) => Query;
21
+ readonly empty: () => Query;
22
+ }
23
+ /**
24
+ * @since 0.1.0
25
+ * @category Models
26
+ */
27
+ type LogicalQuery<Query> = Query | {
28
+ readonly $and: ReadonlyArray<LogicalQuery<Query>>;
29
+ } | {
30
+ readonly $or: ReadonlyArray<LogicalQuery<Query>>;
31
+ } | {
32
+ readonly $not: LogicalQuery<Query>;
33
+ };
34
+ /**
35
+ * Packs JSON-safe raw rules into a compact tuple format.
36
+ *
37
+ * @since 0.1.0
38
+ * @category Conversions
39
+ */
40
+ declare const packRules: <Rule extends RawRule>(rules: Iterable<Rule>) => ReadonlyArray<PackRule<Rule>>;
41
+ /**
42
+ * Unpacks compact raw rules produced by `packRules`.
43
+ *
44
+ * @since 0.1.0
45
+ * @category Conversions
46
+ */
47
+ declare const unpackRules: <Rule extends RawRule = RawRule>(rules: Iterable<PackRule<Rule>>) => ReadonlyArray<Rule>;
48
+ /**
49
+ * Extracts scalar condition values as default fields.
50
+ *
51
+ * @since 0.1.0
52
+ * @category Conversions
53
+ */
54
+ declare const rulesToFields: {
55
+ <Subjects extends SubjectMap, Rules extends AnyRule, Aliases extends ActionAliases, const Request extends RuleQueryRequest<Subjects, Rules, Aliases>>(request: Request): (self: Ability<Subjects, Rules, Aliases>) => Effect.Effect<Readonly<Record<string, unknown>>, QueryGenerationError | SubjectDetectionError>;
56
+ <Subjects extends SubjectMap, Rules extends AnyRule, Aliases extends ActionAliases, const Request extends RuleQueryRequest<Subjects, Rules, Aliases>>(self: Ability<Subjects, Rules, Aliases>, request: Request): Effect.Effect<Readonly<Record<string, unknown>>, QueryGenerationError | SubjectDetectionError>;
57
+ };
58
+ /**
59
+ * Converts rules into a caller-defined logical condition.
60
+ *
61
+ * @since 0.1.0
62
+ * @category Conversions
63
+ */
64
+ declare const rulesToCondition: {
65
+ <Subjects extends SubjectMap, Rules extends AnyRule, Aliases extends ActionAliases, const Request extends RuleQueryRequest<Subjects, Rules, Aliases>, Query, E = never, R = never>(request: Request, convert: (rule: Rules) => Query | Effect.Effect<Query, E, R>, hooks: RulesToConditionHooks<Query>): (self: Ability<Subjects, Rules, Aliases>) => Effect.Effect<Query | null, QueryGenerationError | SubjectDetectionError | E, R>;
66
+ <Subjects extends SubjectMap, Rules extends AnyRule, Aliases extends ActionAliases, const Request extends RuleQueryRequest<Subjects, Rules, Aliases>, Query, E = never, R = never>(self: Ability<Subjects, Rules, Aliases>, request: Request, convert: (rule: Rules) => Query | Effect.Effect<Query, E, R>, hooks: RulesToConditionHooks<Query>): Effect.Effect<Query | null, QueryGenerationError | SubjectDetectionError | E, R>;
67
+ };
68
+ /**
69
+ * Converts rules into a small generic logical query object.
70
+ *
71
+ * @since 0.1.0
72
+ * @category Conversions
73
+ */
74
+ declare const rulesToQuery: {
75
+ <Subjects extends SubjectMap, Rules extends AnyRule, Aliases extends ActionAliases, const Request extends RuleQueryRequest<Subjects, Rules, Aliases>, Query, E = never, R = never>(request: Request, convert: (rule: Rules) => Query | Effect.Effect<Query, E, R>): (self: Ability<Subjects, Rules, Aliases>) => Effect.Effect<LogicalQuery<Query> | null, QueryGenerationError | SubjectDetectionError | E, R>;
76
+ <Subjects extends SubjectMap, Rules extends AnyRule, Aliases extends ActionAliases, const Request extends RuleQueryRequest<Subjects, Rules, Aliases>, Query, E = never, R = never>(self: Ability<Subjects, Rules, Aliases>, request: Request, convert: (rule: Rules) => Query | Effect.Effect<Query, E, R>): Effect.Effect<LogicalQuery<Query> | null, QueryGenerationError | SubjectDetectionError | E, R>;
77
+ };
78
+ //#endregion
79
+ export { AbilityExtra_d_exports, LogicalQuery, PackRule, RulesToConditionHooks, packRules, rulesToCondition, rulesToFields, rulesToQuery, unpackRules };
@@ -0,0 +1,195 @@
1
+ import { __exportAll } from "./_virtual/_rolldown/runtime.js";
2
+ import { cloneSerializable, isPlainObject } from "./internal/serializable.js";
3
+ import { QueryGenerationError, rulesFor } from "./Ability.js";
4
+ import * as Effect from "effect/Effect";
5
+ import { dual } from "effect/Function";
6
+ //#region src/AbilityExtra.ts
7
+ /**
8
+ * Extra helpers for serializing and transforming Ability rules.
9
+ *
10
+ * Mental model:
11
+ * - `AbilityExtra` works with already-defined abilities and JSON-safe rules.
12
+ * - Packing preserves rule structure while reducing wire size.
13
+ * - Query helpers transform rule lists into caller-owned condition formats.
14
+ *
15
+ * Common tasks:
16
+ * - Compact raw rules with {@link packRules} and {@link unpackRules}.
17
+ * - Derive default fields from rule conditions with {@link rulesToFields}.
18
+ * - Convert matching rules to logical conditions with {@link rulesToCondition}
19
+ * or {@link rulesToQuery}.
20
+ *
21
+ * Gotchas:
22
+ * - Query generation rejects function predicates because they cannot be
23
+ * represented as static conditions.
24
+ * - Conversion callbacks may be synchronous or Effectful; synchronous throws are
25
+ * converted to `QueryGenerationError`.
26
+ *
27
+ * @since 0.1.0
28
+ * @module
29
+ */
30
+ var AbilityExtra_exports = /* @__PURE__ */ __exportAll({
31
+ packRules: () => packRules,
32
+ rulesToCondition: () => rulesToCondition,
33
+ rulesToFields: () => rulesToFields,
34
+ rulesToQuery: () => rulesToQuery,
35
+ unpackRules: () => unpackRules
36
+ });
37
+ const forbiddenPathKeys = new Set([
38
+ "__proto__",
39
+ "constructor",
40
+ "prototype"
41
+ ]);
42
+ const setByPath = (object, path, value) => {
43
+ const keys = path.split(".");
44
+ let cursor = object;
45
+ let index = 0;
46
+ while (index < keys.length - 1) {
47
+ const key = keys[index];
48
+ if (key === void 0 || forbiddenPathKeys.has(key)) return;
49
+ const current = cursor[key];
50
+ if (!isPlainObject(current)) {
51
+ const next = {};
52
+ cursor[key] = next;
53
+ cursor = next;
54
+ } else cursor = current;
55
+ index = index + 1;
56
+ }
57
+ const lastKey = keys[keys.length - 1];
58
+ if (lastKey !== void 0 && !forbiddenPathKeys.has(lastKey)) cursor[lastKey] = value;
59
+ };
60
+ const packRule = (rule) => {
61
+ const packed = [
62
+ cloneSerializable(rule.action),
63
+ cloneSerializable(rule.subject),
64
+ rule.conditions === void 0 ? 0 : cloneSerializable(rule.conditions),
65
+ rule.inverted === true ? 1 : 0,
66
+ rule.fields === void 0 ? 0 : cloneSerializable(rule.fields),
67
+ rule.reason ?? ""
68
+ ];
69
+ while (packed.length > 2 && (packed[packed.length - 1] === 0 || packed[packed.length - 1] === "" || packed[packed.length - 1] === void 0)) packed.pop();
70
+ return Object.freeze(packed);
71
+ };
72
+ /**
73
+ * Packs JSON-safe raw rules into a compact tuple format.
74
+ *
75
+ * @since 0.1.0
76
+ * @category Conversions
77
+ */
78
+ const packRules = (rules) => Object.freeze(Array.from(rules, packRule));
79
+ const unpackRule = (packed) => {
80
+ const [action, subject, conditions, inverted, fields, reason] = packed;
81
+ const rule = {
82
+ action: cloneSerializable(action),
83
+ subject: cloneSerializable(subject)
84
+ };
85
+ if (conditions !== void 0 && conditions !== 0) rule.conditions = cloneSerializable(conditions);
86
+ if (inverted === 1) rule.inverted = true;
87
+ if (fields !== void 0 && fields !== 0) rule.fields = cloneSerializable(fields);
88
+ if (reason !== void 0 && reason !== "") rule.reason = reason;
89
+ return Object.freeze(rule);
90
+ };
91
+ /**
92
+ * Unpacks compact raw rules produced by `packRules`.
93
+ *
94
+ * @since 0.1.0
95
+ * @category Conversions
96
+ */
97
+ const unpackRules = (rules) => Object.freeze(Array.from(rules, unpackRule));
98
+ const queryGenerationError = (reason, ruleIndex, cause) => {
99
+ const error = { reason };
100
+ if (ruleIndex !== void 0) error.ruleIndex = ruleIndex;
101
+ if (cause !== void 0) error.cause = cause;
102
+ return new QueryGenerationError(error);
103
+ };
104
+ const assertSerializableRule = (rule, ruleIndex) => {
105
+ if (rule.when !== void 0) return Effect.fail(queryGenerationError("Cannot transform rules with function predicates", ruleIndex));
106
+ return Effect.void;
107
+ };
108
+ /**
109
+ * Extracts scalar condition values as default fields.
110
+ *
111
+ * @since 0.1.0
112
+ * @category Conversions
113
+ */
114
+ const rulesToFields = dual(2, Effect.fnUntraced(function* (self, request) {
115
+ const rules = yield* rulesFor(self, request);
116
+ const fields = {};
117
+ let index = 0;
118
+ for (const rule of rules) {
119
+ yield* assertSerializableRule(rule, index);
120
+ if (rule._tag === "Allow" && rule.conditions !== void 0) for (const key of Object.keys(rule.conditions)) {
121
+ const value = rule.conditions[key];
122
+ if (!isPlainObject(value)) setByPath(fields, key, value);
123
+ }
124
+ index = index + 1;
125
+ }
126
+ return Object.freeze(fields);
127
+ }));
128
+ const convertRule = (rule, convert, ruleIndex) => Effect.flatMap(Effect.try({
129
+ try: () => convert(rule),
130
+ catch: (cause) => queryGenerationError("Rule conversion failed", ruleIndex, cause)
131
+ }), (result) => Effect.isEffect(result) ? result : Effect.succeed(result));
132
+ /**
133
+ * Converts rules into a caller-defined logical condition.
134
+ *
135
+ * @since 0.1.0
136
+ * @category Conversions
137
+ */
138
+ const rulesToConditionEffect = Effect.fnUntraced(function* (self, request, convert, hooks) {
139
+ const rules = yield* rulesFor(self, request);
140
+ const higherDenyBounds = [];
141
+ const orConditions = [];
142
+ let hasUnconditionalAllow = false;
143
+ let index = 0;
144
+ while (index < rules.length) {
145
+ const rule = rules[index];
146
+ yield* assertSerializableRule(rule, index);
147
+ if (rule._tag === "Deny") {
148
+ if (rule.conditions === void 0) break;
149
+ const condition = yield* convertRule(rule, convert, index);
150
+ higherDenyBounds.push(hooks.not(condition));
151
+ } else {
152
+ if (rule.conditions === void 0) {
153
+ hasUnconditionalAllow = true;
154
+ break;
155
+ }
156
+ const condition = yield* convertRule(rule, convert, index);
157
+ orConditions.push(higherDenyBounds.length === 0 ? condition : hooks.and([condition, ...higherDenyBounds]));
158
+ }
159
+ index = index + 1;
160
+ }
161
+ if (hasUnconditionalAllow) {
162
+ if (higherDenyBounds.length === 0) return hooks.empty();
163
+ if (orConditions.length === 0) return hooks.and(higherDenyBounds);
164
+ orConditions.push(hooks.and(higherDenyBounds));
165
+ }
166
+ if (orConditions.length === 0) return null;
167
+ return hooks.or(orConditions);
168
+ });
169
+ /**
170
+ * Converts rules into a caller-defined logical condition.
171
+ *
172
+ * @since 0.1.0
173
+ * @category Conversions
174
+ */
175
+ const rulesToCondition = dual(4, rulesToConditionEffect);
176
+ /**
177
+ * Converts rules into a small generic logical query object.
178
+ *
179
+ * @since 0.1.0
180
+ * @category Conversions
181
+ */
182
+ const rulesToQuery = dual(3, Effect.fnUntraced(function* (self, request, convert) {
183
+ const logicalConvert = (rule) => {
184
+ const result = convert(rule);
185
+ return Effect.isEffect(result) ? result : result;
186
+ };
187
+ return yield* rulesToConditionEffect(self, request, logicalConvert, {
188
+ and: (conditions) => ({ $and: conditions }),
189
+ or: (conditions) => ({ $or: conditions }),
190
+ not: (condition) => ({ $not: condition }),
191
+ empty: () => ({})
192
+ });
193
+ }));
194
+ //#endregion
195
+ export { AbilityExtra_exports, packRules, rulesToCondition, rulesToFields, rulesToQuery, unpackRules };
@@ -0,0 +1,110 @@
1
+ import { Ability, AliasError, AnyRule, MongoCondition, RawRule, RawRuleError, RuleSubject, SubjectMap, SubjectUnion } from "./Ability.js";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Equal from "effect/Equal";
4
+ import * as Inspectable from "effect/Inspectable";
5
+ import * as Pipeable from "effect/Pipeable";
6
+
7
+ //#region src/AbilityRef.d.ts
8
+ declare namespace AbilityRef_d_exports {
9
+ export { AbilityRef, Event, EventHandler, EventName, TypeId, Unsubscribe, UpdateEvent, UpdatedEvent, get, isAbilityRef, make, on, set, update };
10
+ }
11
+ /**
12
+ * @since 0.1.0
13
+ * @category Type Ids
14
+ */
15
+ declare const TypeId: unique symbol;
16
+ /**
17
+ * @since 0.1.0
18
+ * @category Type Ids
19
+ */
20
+ type TypeId = typeof TypeId;
21
+ /**
22
+ * @since 0.1.0
23
+ * @category Models
24
+ */
25
+ type EventName = "update" | "updated";
26
+ /**
27
+ * @since 0.1.0
28
+ * @category Models
29
+ */
30
+ interface UpdateEvent<Subjects extends SubjectMap> {
31
+ readonly previous: Ability<Subjects, AnyRule>;
32
+ readonly next: Ability<Subjects, AnyRule>;
33
+ }
34
+ /**
35
+ * @since 0.1.0
36
+ * @category Models
37
+ */
38
+ interface UpdatedEvent<Subjects extends SubjectMap> {
39
+ readonly previous: Ability<Subjects, AnyRule>;
40
+ readonly current: Ability<Subjects, AnyRule>;
41
+ }
42
+ /**
43
+ * @since 0.1.0
44
+ * @category Models
45
+ */
46
+ type Event<Subjects extends SubjectMap, Name extends EventName> = Name extends "update" ? UpdateEvent<Subjects> : UpdatedEvent<Subjects>;
47
+ /**
48
+ * @since 0.1.0
49
+ * @category Models
50
+ */
51
+ type EventHandler<Subjects extends SubjectMap, Name extends EventName> = (event: Event<Subjects, Name>) => void | Effect.Effect<void>;
52
+ /**
53
+ * @since 0.1.0
54
+ * @category Models
55
+ */
56
+ type Unsubscribe = () => void;
57
+ /**
58
+ * @since 0.1.0
59
+ * @category Models
60
+ */
61
+ interface AbilityRef<Subjects extends SubjectMap> extends Equal.Equal, Inspectable.Inspectable, Pipeable.Pipeable {
62
+ readonly [TypeId]: TypeId;
63
+ readonly current: Ability<Subjects, AnyRule>;
64
+ /** @internal */
65
+ readonly handlers: {
66
+ readonly update: Array<EventHandler<Subjects, "update">>;
67
+ readonly updated: Array<EventHandler<Subjects, "updated">>;
68
+ };
69
+ }
70
+ /**
71
+ * @since 0.1.0
72
+ * @category Constructors
73
+ */
74
+ declare const make: <Subjects extends SubjectMap, Rules extends AnyRule>(ability: Ability<Subjects, Rules>) => AbilityRef<Subjects>;
75
+ /**
76
+ * @since 0.1.0
77
+ * @category Guards
78
+ */
79
+ declare const isAbilityRef: (value: unknown) => value is AbilityRef<SubjectMap>;
80
+ /**
81
+ * @since 0.1.0
82
+ * @category Accessors
83
+ */
84
+ declare const get: <Subjects extends SubjectMap>(self: AbilityRef<Subjects>) => Ability<Subjects, AnyRule>;
85
+ /**
86
+ * @since 0.1.0
87
+ * @category Combinators
88
+ */
89
+ declare const set: {
90
+ <Subjects extends SubjectMap, Rules extends AnyRule>(ability: Ability<Subjects, Rules>): (self: AbilityRef<Subjects>) => Effect.Effect<void>;
91
+ <Subjects extends SubjectMap, Rules extends AnyRule>(self: AbilityRef<Subjects>, ability: Ability<Subjects, Rules>): Effect.Effect<void>;
92
+ };
93
+ /**
94
+ * @since 0.1.0
95
+ * @category Combinators
96
+ */
97
+ declare const update: {
98
+ <Subjects extends SubjectMap, Rules extends AnyRule>(next: Ability<Subjects, Rules> | Iterable<RawRule<string, RuleSubject<Subjects>, string, MongoCondition<SubjectUnion<Subjects>>>>): (self: AbilityRef<Subjects>) => Effect.Effect<void, AliasError | RawRuleError>;
99
+ <Subjects extends SubjectMap, Rules extends AnyRule>(self: AbilityRef<Subjects>, next: Ability<Subjects, Rules> | Iterable<RawRule<string, RuleSubject<Subjects>, string, MongoCondition<SubjectUnion<Subjects>>>>): Effect.Effect<void, AliasError | RawRuleError>;
100
+ };
101
+ /**
102
+ * @since 0.1.0
103
+ * @category Combinators
104
+ */
105
+ declare const on: {
106
+ <Subjects extends SubjectMap, Name extends EventName>(name: Name, handler: EventHandler<Subjects, Name>): (self: AbilityRef<Subjects>) => Effect.Effect<Unsubscribe>;
107
+ <Subjects extends SubjectMap, Name extends EventName>(self: AbilityRef<Subjects>, name: Name, handler: EventHandler<Subjects, Name>): Effect.Effect<Unsubscribe>;
108
+ };
109
+ //#endregion
110
+ export { AbilityRef, AbilityRef_d_exports, Event, EventHandler, EventName, TypeId, Unsubscribe, UpdateEvent, UpdatedEvent, get, isAbilityRef, make, on, set, update };