mdld-parse 0.6.0 → 0.7.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 +100 -473
- package/package.json +1 -1
- package/src/generate.js +5 -89
- package/src/index.js +1 -1
- package/src/locate.js +21 -58
- package/src/merge.js +131 -0
- package/src/parse.js +72 -25
- package/src/utils.js +37 -120
- package/src/applyDiff.js +0 -583
package/src/utils.js
CHANGED
|
@@ -262,6 +262,9 @@ export function expandIRI(term, ctx) {
|
|
|
262
262
|
result = t;
|
|
263
263
|
} else if (t.includes(':')) {
|
|
264
264
|
const [prefix, ref] = t.split(':', 2);
|
|
265
|
+
if (prefix && !ctx[prefix] && prefix !== '@vocab') {
|
|
266
|
+
console.warn(`Undefined prefix "${prefix}" in IRI "${t}" - treating as literal`);
|
|
267
|
+
}
|
|
265
268
|
result = ctx[prefix] ? ctx[prefix] + ref : t;
|
|
266
269
|
} else {
|
|
267
270
|
result = (ctx['@vocab'] || '') + t;
|
|
@@ -314,19 +317,32 @@ export function parseSemanticBlock(raw) {
|
|
|
314
317
|
let m;
|
|
315
318
|
|
|
316
319
|
while ((m = re.exec(cleaned)) !== null) {
|
|
317
|
-
|
|
320
|
+
let token = m[0];
|
|
318
321
|
const relStart = 1 + m.index;
|
|
319
322
|
const relEnd = relStart + token.length;
|
|
320
323
|
const entryIndex = result.entries.length;
|
|
321
324
|
|
|
325
|
+
// Handle remove polarity - strip leading - and set remove flag
|
|
326
|
+
let remove = false;
|
|
327
|
+
if (token.startsWith('-') && token.length > 1) {
|
|
328
|
+
remove = true;
|
|
329
|
+
token = token.slice(1);
|
|
330
|
+
}
|
|
331
|
+
|
|
322
332
|
// Handle special tokens
|
|
323
333
|
if (token === '=') {
|
|
334
|
+
if (remove) {
|
|
335
|
+
console.warn('-= is not valid, subject declarations have no polarity');
|
|
336
|
+
}
|
|
324
337
|
result.subject = 'RESET';
|
|
325
338
|
result.entries.push({ kind: 'subjectReset', relRange: { start: relStart, end: relEnd }, raw: token });
|
|
326
339
|
continue;
|
|
327
340
|
}
|
|
328
341
|
|
|
329
342
|
if (token.startsWith('=') && !token.startsWith('=#')) {
|
|
343
|
+
if (remove) {
|
|
344
|
+
console.warn('-= is not valid, subject declarations have no polarity');
|
|
345
|
+
}
|
|
330
346
|
const iri = token.substring(1);
|
|
331
347
|
result.subject = iri;
|
|
332
348
|
result.entries.push({ kind: 'subject', iri, relRange: { start: relStart, end: relEnd }, raw: token });
|
|
@@ -337,7 +353,7 @@ export function parseSemanticBlock(raw) {
|
|
|
337
353
|
let processed = false;
|
|
338
354
|
for (const [pattern, config] of Object.entries(TOKEN_PATTERNS)) {
|
|
339
355
|
if (token.startsWith(pattern)) {
|
|
340
|
-
const entry = { kind: config.kind, relRange: { start: relStart, end: relEnd }, raw:
|
|
356
|
+
const entry = { kind: config.kind, relRange: { start: relStart, end: relEnd }, raw: m[0] };
|
|
341
357
|
const extracted = config.extract(token);
|
|
342
358
|
|
|
343
359
|
if (config.kind === 'fragment') {
|
|
@@ -347,22 +363,36 @@ export function parseSemanticBlock(raw) {
|
|
|
347
363
|
result.object = `#${extracted}`;
|
|
348
364
|
entry.fragment = extracted;
|
|
349
365
|
} else if (config.kind === 'object') {
|
|
366
|
+
if (remove) {
|
|
367
|
+
console.warn('-+ is not valid, object declarations have no polarity');
|
|
368
|
+
remove = false;
|
|
369
|
+
}
|
|
350
370
|
result.object = extracted;
|
|
351
371
|
entry.iri = extracted;
|
|
352
372
|
} else if (config.kind === 'datatype') {
|
|
373
|
+
if (remove) {
|
|
374
|
+
console.warn('-^^ is not valid, datatype modifiers have no polarity');
|
|
375
|
+
remove = false;
|
|
376
|
+
}
|
|
353
377
|
if (!result.language) result.datatype = extracted;
|
|
354
378
|
entry.datatype = extracted;
|
|
355
379
|
} else if (config.kind === 'language') {
|
|
380
|
+
if (remove) {
|
|
381
|
+
console.warn('-@ is not valid, language modifiers have no polarity');
|
|
382
|
+
remove = false;
|
|
383
|
+
}
|
|
356
384
|
result.language = extracted;
|
|
357
385
|
result.datatype = null;
|
|
358
386
|
entry.language = extracted;
|
|
359
387
|
} else if (config.kind === 'type') {
|
|
360
|
-
result.types.push({ iri: extracted, entryIndex });
|
|
388
|
+
result.types.push({ iri: extracted, entryIndex, remove });
|
|
361
389
|
entry.iri = extracted;
|
|
390
|
+
entry.remove = remove;
|
|
362
391
|
} else if (config.kind === 'property') {
|
|
363
|
-
result.predicates.push({ iri: extracted, form: config.form, entryIndex });
|
|
392
|
+
result.predicates.push({ iri: extracted, form: config.form, entryIndex, remove });
|
|
364
393
|
entry.iri = extracted;
|
|
365
394
|
entry.form = config.form;
|
|
395
|
+
entry.remove = remove;
|
|
366
396
|
}
|
|
367
397
|
|
|
368
398
|
result.entries.push(entry);
|
|
@@ -373,8 +403,8 @@ export function parseSemanticBlock(raw) {
|
|
|
373
403
|
|
|
374
404
|
// Default case (no pattern match)
|
|
375
405
|
if (!processed) {
|
|
376
|
-
result.predicates.push({ iri: token, form: '', entryIndex });
|
|
377
|
-
result.entries.push({ kind: 'property', iri: token, form: '', relRange: { start: relStart, end: relEnd }, raw:
|
|
406
|
+
result.predicates.push({ iri: token, form: '', entryIndex, remove });
|
|
407
|
+
result.entries.push({ kind: 'property', iri: token, form: '', relRange: { start: relStart, end: relEnd }, raw: m[0], remove });
|
|
378
408
|
}
|
|
379
409
|
}
|
|
380
410
|
|
|
@@ -392,121 +422,8 @@ export function quadIndexKey(subject, predicate, object) {
|
|
|
392
422
|
return JSON.stringify([subject.value, predicate.value, objKey]);
|
|
393
423
|
}
|
|
394
424
|
|
|
395
|
-
export function normalizeQuad(q) {
|
|
396
|
-
if (!q) return null;
|
|
397
|
-
const { subject, predicate, object } = q;
|
|
398
|
-
if (object?.termType === 'Literal') {
|
|
399
|
-
const language = typeof object.language === 'string' ? object.language : '';
|
|
400
|
-
const datatype = object.datatype || { termType: 'NamedNode', value: 'http://www.w3.org/2001/XMLSchema#string' };
|
|
401
|
-
return { ...q, subject, predicate, object: { ...object, language, datatype } };
|
|
402
|
-
}
|
|
403
|
-
return { ...q, subject, predicate, object };
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
export function objectSignature(o) {
|
|
407
|
-
if (!o) return '';
|
|
408
|
-
if (o.termType === 'Literal') {
|
|
409
|
-
return JSON.stringify({ t: 'Literal', v: o.value, lang: o.language || '', dt: o.datatype?.value || '' });
|
|
410
|
-
}
|
|
411
|
-
return JSON.stringify({ t: o.termType, v: o.value });
|
|
412
|
-
}
|
|
413
|
-
|
|
414
425
|
export function quadToKeyForOrigin(q) {
|
|
415
|
-
|
|
416
|
-
return nq ? quadIndexKey(nq.subject, nq.predicate, nq.object) : null;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
export function parseQuadIndexKey(key) {
|
|
420
|
-
try {
|
|
421
|
-
const [s, p, objKey] = JSON.parse(key);
|
|
422
|
-
return { s, p, o: JSON.parse(objKey) };
|
|
423
|
-
} catch {
|
|
424
|
-
return null;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Direct slot management functions - unified with block data
|
|
429
|
-
export function createUnifiedSlot(block, entryIndex, meta = {}) {
|
|
430
|
-
const slotId = meta.subject && meta.predicate ? hash(`${meta.subject.value}|${meta.predicate.value}`) : null;
|
|
431
|
-
return {
|
|
432
|
-
// Block metadata
|
|
433
|
-
id: block.id,
|
|
434
|
-
range: block.range,
|
|
435
|
-
attrsRange: block.attrsRange,
|
|
436
|
-
valueRange: block.valueRange,
|
|
437
|
-
carrierType: block.carrierType,
|
|
438
|
-
subject: block.subject,
|
|
439
|
-
types: block.types,
|
|
440
|
-
predicates: block.predicates,
|
|
441
|
-
context: block.context,
|
|
442
|
-
|
|
443
|
-
// Slot metadata
|
|
444
|
-
entryIndex,
|
|
445
|
-
slotId,
|
|
446
|
-
isVacant: false,
|
|
447
|
-
lastValue: null,
|
|
448
|
-
vacantSince: null,
|
|
449
|
-
|
|
450
|
-
// Quad metadata
|
|
451
|
-
...meta
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
export function markSlotAsVacant(slotInfo, deletedValue) {
|
|
456
|
-
return slotInfo ? {
|
|
457
|
-
...slotInfo,
|
|
458
|
-
isVacant: true,
|
|
459
|
-
lastValue: deletedValue,
|
|
460
|
-
vacantSince: Date.now()
|
|
461
|
-
} : null;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
export function findVacantSlot(quadMap, subject, predicate) {
|
|
465
|
-
const targetSlotId = hash(`${subject.value}|${predicate.value}`);
|
|
466
|
-
return Array.from(quadMap.values())
|
|
467
|
-
.find(slot => slot.slotId === targetSlotId && slot.isVacant);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
export function occupySlot(slotInfo, newValue) {
|
|
471
|
-
return slotInfo && slotInfo.isVacant ? {
|
|
472
|
-
...slotInfo,
|
|
473
|
-
isVacant: false,
|
|
474
|
-
lastValue: newValue,
|
|
475
|
-
vacantSince: null
|
|
476
|
-
} : null;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
export function normalizeAttrsTokens(attrsText) {
|
|
480
|
-
const cleaned = String(attrsText || '').replace(/^\s*\{|\}\s*$/g, '').trim();
|
|
481
|
-
return cleaned ? cleaned.split(/\s+/).filter(Boolean) : [];
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
export function writeAttrsTokens(tokens) {
|
|
485
|
-
return `{${tokens.join(' ').trim()}}`;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
export function removeOneToken(tokens, matchFn) {
|
|
489
|
-
const i = tokens.findIndex(matchFn);
|
|
490
|
-
return i === -1 ? { tokens, removed: false } : { tokens: [...tokens.slice(0, i), ...tokens.slice(i + 1)], removed: true };
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// Direct token management - no wrapper function needed
|
|
494
|
-
export function addObjectToken(tokens, iri) {
|
|
495
|
-
const token = `+${iri}`;
|
|
496
|
-
return tokens.includes(token) ? tokens : [...tokens, token];
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
export function removeObjectToken(tokens, iri) {
|
|
500
|
-
return removeOneToken(tokens, t => t === `+${iri}`);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
export function addSoftFragmentToken(tokens, fragment) {
|
|
504
|
-
const token = `+#${fragment}`;
|
|
505
|
-
return tokens.includes(token) ? tokens : [...tokens, token];
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
export function removeSoftFragmentToken(tokens, fragment) {
|
|
509
|
-
return removeOneToken(tokens, t => t === `+#${fragment}`);
|
|
426
|
+
return q ? quadIndexKey(q.subject, q.predicate, q.object) : null;
|
|
510
427
|
}
|
|
511
428
|
|
|
512
429
|
export function createLiteral(value, datatype, language, context, dataFactory) {
|