@higher.archi/boe 1.0.24 → 1.0.26
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/dist/engines/sentiment/compiler.d.ts +12 -0
- package/dist/engines/sentiment/compiler.d.ts.map +1 -0
- package/dist/engines/sentiment/compiler.js +111 -0
- package/dist/engines/sentiment/compiler.js.map +1 -0
- package/dist/engines/sentiment/engine.d.ts +47 -0
- package/dist/engines/sentiment/engine.d.ts.map +1 -0
- package/dist/engines/sentiment/engine.js +89 -0
- package/dist/engines/sentiment/engine.js.map +1 -0
- package/dist/engines/sentiment/index.d.ts +9 -0
- package/dist/engines/sentiment/index.d.ts.map +1 -0
- package/dist/engines/sentiment/index.js +21 -0
- package/dist/engines/sentiment/index.js.map +1 -0
- package/dist/engines/sentiment/strategy.d.ts +19 -0
- package/dist/engines/sentiment/strategy.d.ts.map +1 -0
- package/dist/engines/sentiment/strategy.js +398 -0
- package/dist/engines/sentiment/strategy.js.map +1 -0
- package/dist/engines/sentiment/types.d.ts +125 -0
- package/dist/engines/sentiment/types.d.ts.map +1 -0
- package/dist/engines/sentiment/types.js +31 -0
- package/dist/engines/sentiment/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engines/sentiment/compiler.ts +138 -0
- package/src/engines/sentiment/engine.ts +118 -0
- package/src/engines/sentiment/index.ts +41 -0
- package/src/engines/sentiment/strategy.ts +510 -0
- package/src/engines/sentiment/types.ts +188 -0
- package/src/index.ts +31 -0
package/dist/index.js
CHANGED
|
@@ -29,9 +29,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
29
29
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
30
30
|
};
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
-
exports.
|
|
33
|
-
exports.
|
|
34
|
-
exports.resolveDecayTimestamp = exports.calculateDecayMultiplier = exports.RuntimeError = exports.CompilationError = exports.BOEError = exports.cosineSimilarity = exports.caverphone2 = exports.nysiis = exports.soundex = exports.resolveTrendDirection = exports.resolveConfidenceBracket = exports.isHorizonPreset = exports.isSmoothingPreset = exports.HORIZON_PRESET_VALUES = exports.SMOOTHING_PRESET_VALUES = void 0;
|
|
32
|
+
exports.SEMANTIC_WEIGHTS = exports.constraintStrategy = exports.compileConstraintRuleSet = exports.ConstraintStrategy = exports.stateMachineStrategy = exports.compileStateMachineDefinition = exports.compileStateMachine = exports.StateMachineStrategy = exports.monteCarloStrategy = exports.compileMonteCarloRuleSet = exports.MonteCarloStrategy = exports.SEMANTIC_LIKELIHOODS = exports.parseLikelihood = exports.bayesianStrategy = exports.compileBayesianRule = exports.compileBayesianRuleSet = exports.BayesianStrategy = exports.autoAdjustCoverage = exports.analyzeCoverage = exports.compileFuzzyVariable = exports.fuzzyStrategy = exports.compileFuzzyRuleSet = exports.FuzzyStrategy = exports.sequentialStrategy = exports.compileSequentialRuleSet = exports.SequentialStrategy = exports.createScoreFunction = exports.scoringStrategy = exports.compileScoringRuleSet = exports.ScoringStrategy = exports.backwardStrategy = exports.compileBackwardRuleSet = exports.BackwardChainingStrategy = exports.forwardStrategy = exports.compileForwardRule = exports.compileForwardRuleSet = exports.ForwardChainingStrategy = exports.SentimentEngine = exports.EnsembleEngine = exports.PricingEngine = exports.UtilityEngine = exports.ConstraintEngine = exports.StateMachineEngine = exports.MonteCarloEngine = exports.BayesianEngine = exports.FuzzyEngine = exports.SequentialEngine = exports.ScoringEngine = exports.BackwardEngine = exports.ForwardEngine = void 0;
|
|
33
|
+
exports.compilePredictionRuleSet = exports.PredictionExecutor = exports.PredictionEngine = exports.resolveMovement = exports.resolvePercentileLabel = exports.isKFactorPreset = exports.K_FACTOR_VALUES = exports.rankingStrategy = exports.compileRankingRuleSet = exports.RankingExecutor = exports.RankingEngine = exports.scoringMember = exports.expertMember = exports.monteCarloMember = exports.fuzzyMember = exports.bayesianMember = exports.summarizeEnsemble = exports.ensembleStrategy = exports.compileEnsembleRuleSet = exports.EnsembleStrategy = exports.getCurrencyInfo = exports.CURRENCIES = exports.applyMinMax = exports.calculateDiscount = exports.round = exports.formatPercent = exports.formatNumber = exports.formatCurrency = exports.calculateVolume = exports.calculateGraduated = exports.calculateFlat = exports.pricingEngine = exports.pricingStrategy = exports.compilePricingRule = exports.compilePricingRuleSet = exports.PricingStrategy = exports.buildAvailableRefs = exports.hasInterpolation = exports.interpolate = exports.compileTemplate = exports.expertStrategy = exports.compileExpertRuleSet = exports.ExpertStrategy = exports.ExpertEngine = exports.compileDefeasibleRuleSet = exports.DefeasibleEngine = exports.utilityStrategy = exports.compileUtilityRule = exports.compileUtilityRuleSet = exports.UtilityStrategy = void 0;
|
|
34
|
+
exports.resolveDecayTimestamp = exports.calculateDecayMultiplier = exports.RuntimeError = exports.CompilationError = exports.BOEError = exports.cosineSimilarity = exports.caverphone2 = exports.nysiis = exports.soundex = exports.resolveSentimentLabel = exports.SENTIMENT_DEFAULTS = exports.sentimentStrategy = exports.compileSentimentRuleSet = exports.SentimentExecutor = exports.resolveTrendDirection = exports.resolveConfidenceBracket = exports.isHorizonPreset = exports.isSmoothingPreset = exports.HORIZON_PRESET_VALUES = exports.SMOOTHING_PRESET_VALUES = exports.predictionStrategy = void 0;
|
|
35
35
|
// ========================================
|
|
36
36
|
// Engines
|
|
37
37
|
// ========================================
|
|
@@ -60,6 +60,8 @@ var pricing_1 = require("./engines/pricing");
|
|
|
60
60
|
Object.defineProperty(exports, "PricingEngine", { enumerable: true, get: function () { return pricing_1.PricingEngine; } });
|
|
61
61
|
var ensemble_1 = require("./engines/ensemble");
|
|
62
62
|
Object.defineProperty(exports, "EnsembleEngine", { enumerable: true, get: function () { return ensemble_1.EnsembleEngine; } });
|
|
63
|
+
var sentiment_1 = require("./engines/sentiment");
|
|
64
|
+
Object.defineProperty(exports, "SentimentEngine", { enumerable: true, get: function () { return sentiment_1.SentimentEngine; } });
|
|
63
65
|
// ========================================
|
|
64
66
|
// Core Types & Utilities
|
|
65
67
|
// ========================================
|
|
@@ -198,6 +200,13 @@ Object.defineProperty(exports, "isSmoothingPreset", { enumerable: true, get: fun
|
|
|
198
200
|
Object.defineProperty(exports, "isHorizonPreset", { enumerable: true, get: function () { return prediction_1.isHorizonPreset; } });
|
|
199
201
|
Object.defineProperty(exports, "resolveConfidenceBracket", { enumerable: true, get: function () { return prediction_1.resolveConfidenceBracket; } });
|
|
200
202
|
Object.defineProperty(exports, "resolveTrendDirection", { enumerable: true, get: function () { return prediction_1.resolveTrendDirection; } });
|
|
203
|
+
// Sentiment
|
|
204
|
+
var sentiment_2 = require("./engines/sentiment");
|
|
205
|
+
Object.defineProperty(exports, "SentimentExecutor", { enumerable: true, get: function () { return sentiment_2.SentimentExecutor; } });
|
|
206
|
+
Object.defineProperty(exports, "compileSentimentRuleSet", { enumerable: true, get: function () { return sentiment_2.compileSentimentRuleSet; } });
|
|
207
|
+
Object.defineProperty(exports, "sentimentStrategy", { enumerable: true, get: function () { return sentiment_2.sentimentStrategy; } });
|
|
208
|
+
Object.defineProperty(exports, "SENTIMENT_DEFAULTS", { enumerable: true, get: function () { return sentiment_2.SENTIMENT_DEFAULTS; } });
|
|
209
|
+
Object.defineProperty(exports, "resolveSentimentLabel", { enumerable: true, get: function () { return sentiment_2.resolveSentimentLabel; } });
|
|
201
210
|
// ========================================
|
|
202
211
|
// Utility Functions (from old modules, re-exported for convenience)
|
|
203
212
|
// ========================================
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;AAEH,2CAA2C;AAC3C,UAAU;AACV,2CAA2C;AAE3C,iEAAiE;AACjE,6CAAkD;AAAzC,wGAAA,aAAa,OAAA;AACtB,+CAAoD;AAA3C,0GAAA,cAAc,OAAA;AACvB,6CAAkD;AAAzC,wGAAA,aAAa,OAAA;AACtB,mDAAwD;AAA/C,8GAAA,gBAAgB,OAAA;AACzB,yCAA8C;AAArC,oGAAA,WAAW,OAAA;AACpB,+CAAoD;AAA3C,0GAAA,cAAc,OAAA;AACvB,qDAAyD;AAAhD,+GAAA,gBAAgB,OAAA;AACzB,yDAA6D;AAApD,mHAAA,kBAAkB,OAAA;AAC3B,mDAAwD;AAA/C,8GAAA,gBAAgB,OAAA;AACzB,6CAAkD;AAAzC,wGAAA,aAAa,OAAA;AACtB,6CAAkD;AAAzC,wGAAA,aAAa,OAAA;AACtB,+CAAoD;AAA3C,0GAAA,cAAc,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@higher.archi/boe",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.26",
|
|
4
4
|
"description": "A multi-strategy rule engine supporting forward chaining, backward chaining, scoring, sequential, fuzzy logic, and Bayesian inference",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentiment Engine Compiler
|
|
3
|
+
*
|
|
4
|
+
* Validates sentiment rulesets, normalizes lexicon keys to lowercase,
|
|
5
|
+
* and resolves config defaults.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { CompilationError } from '../../core/errors';
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
SentimentRuleSet,
|
|
12
|
+
CompiledSentimentRuleSet,
|
|
13
|
+
CompiledSentimentLexicon,
|
|
14
|
+
CompiledTokenLevelSentimentRuleSet,
|
|
15
|
+
CompiledDocumentLevelSentimentRuleSet,
|
|
16
|
+
CompiledAspectBasedSentimentRuleSet
|
|
17
|
+
} from './types';
|
|
18
|
+
import { SENTIMENT_DEFAULTS } from './types';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Compile and validate a sentiment ruleset.
|
|
22
|
+
*/
|
|
23
|
+
export function compileSentimentRuleSet(
|
|
24
|
+
ruleSet: SentimentRuleSet
|
|
25
|
+
): CompiledSentimentRuleSet {
|
|
26
|
+
if (!ruleSet.id) {
|
|
27
|
+
throw new CompilationError('Sentiment ruleset requires an id');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (ruleSet.mode !== 'sentiment') {
|
|
31
|
+
throw new CompilationError(`Expected mode 'sentiment', got '${ruleSet.mode}'`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!ruleSet.lexiconConfig || !ruleSet.lexiconConfig.lexicon) {
|
|
35
|
+
throw new CompilationError('Sentiment ruleset requires a lexiconConfig with a lexicon');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const lexiconKeys = Object.keys(ruleSet.lexiconConfig.lexicon);
|
|
39
|
+
if (lexiconKeys.length === 0) {
|
|
40
|
+
throw new CompilationError('Lexicon must contain at least one entry');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Compile the lexicon
|
|
44
|
+
const lexicon = compileLexicon(ruleSet.lexiconConfig);
|
|
45
|
+
|
|
46
|
+
// Resolve config defaults
|
|
47
|
+
const config = {
|
|
48
|
+
capsBoost: ruleSet.config?.capsBoost ?? SENTIMENT_DEFAULTS.capsBoost,
|
|
49
|
+
exclamationBoost: ruleSet.config?.exclamationBoost ?? SENTIMENT_DEFAULTS.exclamationBoost,
|
|
50
|
+
negationWindow: ruleSet.config?.negationWindow ?? SENTIMENT_DEFAULTS.negationWindow
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
switch (ruleSet.strategy) {
|
|
54
|
+
case 'token-level':
|
|
55
|
+
return {
|
|
56
|
+
id: ruleSet.id,
|
|
57
|
+
name: ruleSet.name,
|
|
58
|
+
mode: 'sentiment',
|
|
59
|
+
strategy: 'token-level',
|
|
60
|
+
lexicon,
|
|
61
|
+
config
|
|
62
|
+
} satisfies CompiledTokenLevelSentimentRuleSet;
|
|
63
|
+
|
|
64
|
+
case 'document-level': {
|
|
65
|
+
const pattern = ruleSet.sentenceSplitPattern ?? '[.!?]+';
|
|
66
|
+
return {
|
|
67
|
+
id: ruleSet.id,
|
|
68
|
+
name: ruleSet.name,
|
|
69
|
+
mode: 'sentiment',
|
|
70
|
+
strategy: 'document-level',
|
|
71
|
+
lexicon,
|
|
72
|
+
config,
|
|
73
|
+
sentenceSplitPattern: new RegExp(pattern)
|
|
74
|
+
} satisfies CompiledDocumentLevelSentimentRuleSet;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
case 'aspect-based': {
|
|
78
|
+
if (!ruleSet.aspects || ruleSet.aspects.length === 0) {
|
|
79
|
+
throw new CompilationError('Aspect-based strategy requires at least one aspect');
|
|
80
|
+
}
|
|
81
|
+
const aspects = ruleSet.aspects.map(a => a.toLowerCase());
|
|
82
|
+
return {
|
|
83
|
+
id: ruleSet.id,
|
|
84
|
+
name: ruleSet.name,
|
|
85
|
+
mode: 'sentiment',
|
|
86
|
+
strategy: 'aspect-based',
|
|
87
|
+
lexicon,
|
|
88
|
+
config,
|
|
89
|
+
aspects
|
|
90
|
+
} satisfies CompiledAspectBasedSentimentRuleSet;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
default:
|
|
94
|
+
throw new CompilationError(`Unknown sentiment strategy: '${(ruleSet as any).strategy}'`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function compileLexicon(
|
|
99
|
+
input: { lexicon: Record<string, number>; boosters?: Record<string, number>; negation?: string[]; idioms?: Record<string, number> }
|
|
100
|
+
): CompiledSentimentLexicon {
|
|
101
|
+
// Normalize all keys to lowercase
|
|
102
|
+
const lexicon: Record<string, number> = {};
|
|
103
|
+
for (const [key, value] of Object.entries(input.lexicon)) {
|
|
104
|
+
lexicon[key.toLowerCase()] = value;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const boosters: Record<string, number> = {};
|
|
108
|
+
if (input.boosters) {
|
|
109
|
+
for (const [key, value] of Object.entries(input.boosters)) {
|
|
110
|
+
boosters[key.toLowerCase()] = value;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const negation = new Set<string>(
|
|
115
|
+
(input.negation ?? []).map(w => w.toLowerCase())
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const idioms: Record<string, number> = {};
|
|
119
|
+
let idiomMaxLength = 0;
|
|
120
|
+
if (input.idioms) {
|
|
121
|
+
for (const [key, value] of Object.entries(input.idioms)) {
|
|
122
|
+
const normalized = key.toLowerCase();
|
|
123
|
+
idioms[normalized] = value;
|
|
124
|
+
const wordCount = normalized.split(/\s+/).length;
|
|
125
|
+
if (wordCount > idiomMaxLength) {
|
|
126
|
+
idiomMaxLength = wordCount;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
lexicon,
|
|
133
|
+
boosters,
|
|
134
|
+
negation,
|
|
135
|
+
idioms,
|
|
136
|
+
_idiomMaxLength: idiomMaxLength
|
|
137
|
+
};
|
|
138
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentiment Engine
|
|
3
|
+
*
|
|
4
|
+
* Text sentiment analysis engine that scores text using dictionary-lookup
|
|
5
|
+
* and heuristic rules. Supports token-level, document-level, and aspect-based
|
|
6
|
+
* analysis strategies with injectable lexicon configuration.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const engine = new SentimentEngine();
|
|
11
|
+
* engine.add({ type: 'Review', data: { text: 'The product is absolutely fantastic!' } });
|
|
12
|
+
*
|
|
13
|
+
* const result = engine.execute(compiledRuleset);
|
|
14
|
+
* console.log(result.compound); // 0.85 (positive)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
WorkingMemory,
|
|
20
|
+
Fact,
|
|
21
|
+
FactInput,
|
|
22
|
+
FactChange
|
|
23
|
+
} from '../../core';
|
|
24
|
+
|
|
25
|
+
import type {
|
|
26
|
+
CompiledSentimentRuleSet,
|
|
27
|
+
SentimentOptions,
|
|
28
|
+
SentimentResult
|
|
29
|
+
} from './types';
|
|
30
|
+
|
|
31
|
+
import { SentimentExecutor } from './strategy';
|
|
32
|
+
|
|
33
|
+
export class SentimentEngine {
|
|
34
|
+
private wm: WorkingMemory;
|
|
35
|
+
private strategy: SentimentExecutor;
|
|
36
|
+
|
|
37
|
+
constructor(workingMemory?: WorkingMemory) {
|
|
38
|
+
this.wm = workingMemory ?? new WorkingMemory();
|
|
39
|
+
this.strategy = new SentimentExecutor();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ========================================
|
|
43
|
+
// IWorkingMemory Implementation
|
|
44
|
+
// ========================================
|
|
45
|
+
|
|
46
|
+
add<T = Record<string, any>>(input: FactInput<T>): Fact<T> {
|
|
47
|
+
return this.wm.add(input);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
remove(factId: string): Fact | undefined {
|
|
51
|
+
return this.wm.remove(factId);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
update<T = Record<string, any>>(input: FactInput<T>): Fact<T> {
|
|
55
|
+
return this.wm.update(input);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get(factId: string): Fact | undefined {
|
|
59
|
+
return this.wm.get(factId);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getByType(type: string): Fact[] {
|
|
63
|
+
return this.wm.getByType(type);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
getAll(): Fact[] {
|
|
67
|
+
return this.wm.getAll();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
has(factId: string): boolean {
|
|
71
|
+
return this.wm.has(factId);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
size(): number {
|
|
75
|
+
return this.wm.size();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
clear(): void {
|
|
79
|
+
this.wm.clear();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
getChanges(): FactChange[] {
|
|
83
|
+
return this.wm.getChanges();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
clearChanges(): void {
|
|
87
|
+
this.wm.clearChanges();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ========================================
|
|
91
|
+
// Engine Execution
|
|
92
|
+
// ========================================
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Execute a sentiment analysis ruleset.
|
|
96
|
+
*
|
|
97
|
+
* Extracts text from all facts in working memory, applies the configured
|
|
98
|
+
* sentiment strategy, and returns compound scores with token-level detail.
|
|
99
|
+
*
|
|
100
|
+
* @param ruleSet - Compiled sentiment ruleset
|
|
101
|
+
* @param options - Runtime options (onToken callback)
|
|
102
|
+
* @returns Sentiment result with compound score, label, and detail
|
|
103
|
+
*/
|
|
104
|
+
execute(
|
|
105
|
+
ruleSet: CompiledSentimentRuleSet,
|
|
106
|
+
options: SentimentOptions = {}
|
|
107
|
+
): SentimentResult {
|
|
108
|
+
return this.strategy.run(ruleSet, this.wm, options);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ========================================
|
|
112
|
+
// Utility Methods
|
|
113
|
+
// ========================================
|
|
114
|
+
|
|
115
|
+
getWorkingMemory(): WorkingMemory {
|
|
116
|
+
return this.wm;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentiment Engine -- Text Sentiment Analysis
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Types
|
|
6
|
+
export type {
|
|
7
|
+
SentimentStrategy,
|
|
8
|
+
SentimentLabel,
|
|
9
|
+
SentimentLexicon,
|
|
10
|
+
CompiledSentimentLexicon,
|
|
11
|
+
SentimentConfig,
|
|
12
|
+
TokenLevelSentimentRuleSet,
|
|
13
|
+
DocumentLevelSentimentRuleSet,
|
|
14
|
+
AspectBasedSentimentRuleSet,
|
|
15
|
+
SentimentRuleSet,
|
|
16
|
+
CompiledTokenLevelSentimentRuleSet,
|
|
17
|
+
CompiledDocumentLevelSentimentRuleSet,
|
|
18
|
+
CompiledAspectBasedSentimentRuleSet,
|
|
19
|
+
CompiledSentimentRuleSet,
|
|
20
|
+
TokenModifier,
|
|
21
|
+
TokenScore,
|
|
22
|
+
SentenceResult,
|
|
23
|
+
AspectResult,
|
|
24
|
+
SentimentResult,
|
|
25
|
+
SentimentOptions
|
|
26
|
+
} from './types';
|
|
27
|
+
|
|
28
|
+
// Constants & utilities
|
|
29
|
+
export {
|
|
30
|
+
SENTIMENT_DEFAULTS,
|
|
31
|
+
resolveSentimentLabel
|
|
32
|
+
} from './types';
|
|
33
|
+
|
|
34
|
+
// Compiler
|
|
35
|
+
export { compileSentimentRuleSet } from './compiler';
|
|
36
|
+
|
|
37
|
+
// Strategy
|
|
38
|
+
export { SentimentExecutor, sentimentStrategy } from './strategy';
|
|
39
|
+
|
|
40
|
+
// Engine
|
|
41
|
+
export { SentimentEngine } from './engine';
|