lexorank
This commit is contained in:
@@ -52,9 +52,8 @@
|
|||||||
window.location = channel.lucentUrl;
|
window.location = channel.lucentUrl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
graph = [...response.data.graph];
|
||||||
form.setOriginalData();
|
form.setOriginalData();
|
||||||
graph = response.data.graph;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(null);
|
resolve(null);
|
||||||
@@ -87,7 +86,7 @@
|
|||||||
bind:this={form}
|
bind:this={form}
|
||||||
data={record.data}
|
data={record.data}
|
||||||
status={record.status}
|
status={record.status}
|
||||||
{graph}
|
bind:graph
|
||||||
{schema}
|
{schema}
|
||||||
{record}
|
{record}
|
||||||
{isCreateMode}
|
{isCreateMode}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
export let record;
|
export let record;
|
||||||
export let data;
|
export let data;
|
||||||
export let status = null;
|
export let status = null;
|
||||||
export let graph = [];
|
export let graph;
|
||||||
export let isCreateMode;
|
export let isCreateMode;
|
||||||
let originalContent;
|
let originalContent;
|
||||||
let activeContentTab = "";
|
let activeContentTab = "";
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ use Lucent\Record\Status;
|
|||||||
use Lucent\Schema\Schema\System;
|
use Lucent\Schema\Schema\System;
|
||||||
use Lucent\Schema\Validator\ValidatorException;
|
use Lucent\Schema\Validator\ValidatorException;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
use Lucent\Support\Result\Result;
|
|
||||||
use Lucent\Support\Result\Success;
|
use Lucent\Support\Result\Success;
|
||||||
use Lucent\Svelte\Svelte;
|
use Lucent\Svelte\Svelte;
|
||||||
use PhpOption\Option;
|
use PhpOption\Option;
|
||||||
@@ -315,7 +314,6 @@ class RecordController extends Controller
|
|||||||
{
|
{
|
||||||
$recordId = $request->input("id");
|
$recordId = $request->input("id");
|
||||||
|
|
||||||
|
|
||||||
$recordEdgeData = (new Collection($request->input("edges")))->map(fn($item) => new RecordEdgeData(
|
$recordEdgeData = (new Collection($request->input("edges")))->map(fn($item) => new RecordEdgeData(
|
||||||
target: $item["target"],
|
target: $item["target"],
|
||||||
targetSchema:$item["targetSchema"],
|
targetSchema:$item["targetSchema"],
|
||||||
@@ -323,7 +321,6 @@ class RecordController extends Controller
|
|||||||
data: Option::fromValue(data_get($item,"data")),
|
data: Option::fromValue(data_get($item,"data")),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
$res = match ($request->input("isCreateMode")) {
|
$res = match ($request->input("isCreateMode")) {
|
||||||
true => $this->recordService->createDocument(new NewDocumentData(
|
true => $this->recordService->createDocument(new NewDocumentData(
|
||||||
schemaName: $request->input("schemaName"),
|
schemaName: $request->input("schemaName"),
|
||||||
@@ -368,7 +365,6 @@ class RecordController extends Controller
|
|||||||
public function clone(Request $request)
|
public function clone(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$newRecordId = $this->recordService->clone(
|
$newRecordId = $this->recordService->clone(
|
||||||
recordId: $request->route("rid"),
|
recordId: $request->route("rid"),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Lexorank;
|
||||||
|
|
||||||
|
use Lucent\Support\Result\Error;
|
||||||
|
use Lucent\Support\Result\Result;
|
||||||
|
use function chr;
|
||||||
|
use function in_array;
|
||||||
|
use function ord;
|
||||||
|
use function strcmp;
|
||||||
|
use function substr;
|
||||||
|
|
||||||
|
/** @psalm-immutable */
|
||||||
|
final class Lexorank
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Result<Rank|string>
|
||||||
|
*/
|
||||||
|
public function after(string $prevRank): Result
|
||||||
|
{
|
||||||
|
|
||||||
|
if (empty($prevRank)) {
|
||||||
|
return $this->forEmptySequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = Rank::fromString($prevRank);
|
||||||
|
if($res->error()->isDefined()){
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
$prevRank = $res->success()->get();
|
||||||
|
$char = substr($prevRank->get(), -1);
|
||||||
|
|
||||||
|
if (ord($char) + 1 >= ord(Rank::MAX_CHAR)) {
|
||||||
|
return Rank::fromString(
|
||||||
|
$prevRank->get() . chr(ord(Rank::MIN_CHAR) + 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = substr($prevRank->get(), 0, -1) . chr(ord($char) + 1);
|
||||||
|
|
||||||
|
if(empty($return)){
|
||||||
|
return Error::create("Lexorank empty string error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Rank::fromString($return);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Result<Rank|string>
|
||||||
|
*/
|
||||||
|
public function before(string $nextRank): Result
|
||||||
|
{
|
||||||
|
if (empty($nextRank)) {
|
||||||
|
return $this->forEmptySequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = Rank::fromString($nextRank);
|
||||||
|
if($res->error()->isDefined()){
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nextRank = $res->success()->get();
|
||||||
|
$char = substr($nextRank->get(), -1);
|
||||||
|
|
||||||
|
if (ord($char) - 1 <= ord(Rank::MIN_CHAR)) {
|
||||||
|
$return = substr($nextRank->get(), 0, -1) . chr(ord($char) - 1) . chr(ord(Rank::MAX_CHAR) - 1);
|
||||||
|
return Rank::fromString($return);
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = substr($nextRank->get(), 0, -1) . chr(ord($char) - 1);
|
||||||
|
return Rank::fromString($return);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Result<Rank|string>
|
||||||
|
*/
|
||||||
|
public function betweenRanks(string $prevRank, string $nextRank): Result
|
||||||
|
{
|
||||||
|
$resNext = Rank::fromString($nextRank);
|
||||||
|
$resPrev = Rank::fromString($prevRank);
|
||||||
|
if($resNext->error()->isDefined()){
|
||||||
|
return $resNext;
|
||||||
|
}
|
||||||
|
if($resPrev->error()->isDefined()){
|
||||||
|
return $resPrev;
|
||||||
|
}
|
||||||
|
$nextRank = $resNext->success()->get();
|
||||||
|
$prevRank = $resPrev->success()->get();
|
||||||
|
|
||||||
|
if (strcmp($prevRank->get(), $nextRank->get()) >= 0) {
|
||||||
|
return Error::create('Previous Rank (' . $prevRank->get() . ') is greater than or equals to Next (' . $nextRank->get() . ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rank = '';
|
||||||
|
$i = 0;
|
||||||
|
while ($i <= Rank::MAX_RANK_LEN) {
|
||||||
|
$prevChar = $prevRank->getChar($i, Rank::MIN_CHAR);
|
||||||
|
$nextChar = $nextRank->getChar($i, Rank::MAX_CHAR);
|
||||||
|
$i++;
|
||||||
|
|
||||||
|
$midChar = $this->mid($prevChar, $nextChar);
|
||||||
|
if (in_array($midChar, [$prevChar, $nextChar])) {
|
||||||
|
$rank .= $prevChar;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rank .= $midChar;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Rank::fromString($rank);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Result<Rank|string>
|
||||||
|
*/
|
||||||
|
public function forEmptySequence(): Result
|
||||||
|
{
|
||||||
|
return Rank::fromString($this->mid(Rank::MIN_CHAR, Rank::MAX_CHAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function mid(string $prev, string $next): string
|
||||||
|
{
|
||||||
|
if (ord($prev) >= ord($next)) {
|
||||||
|
return $prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chr((int)((ord($prev) + ord($next)) / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Lexorank;
|
||||||
|
|
||||||
|
use Lucent\Support\Result\Error;
|
||||||
|
use Lucent\Support\Result\Result;
|
||||||
|
use Lucent\Support\Result\Success;
|
||||||
|
use function array_filter;
|
||||||
|
use function array_values;
|
||||||
|
use function ord;
|
||||||
|
use function str_split;
|
||||||
|
use function strlen;
|
||||||
|
use function substr;
|
||||||
|
|
||||||
|
/** @psalm-immutable */
|
||||||
|
final class Rank
|
||||||
|
{
|
||||||
|
public const MIN_CHAR = '0';
|
||||||
|
|
||||||
|
public const MAX_CHAR = 'z';
|
||||||
|
|
||||||
|
/** Usually, database like MySQL order using only the first 1024 chars */
|
||||||
|
public const MAX_RANK_LEN = 1024;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var non-empty-string
|
||||||
|
* @psalm-readonly
|
||||||
|
*/
|
||||||
|
private string $rank;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param non-empty-string $rank
|
||||||
|
*/
|
||||||
|
public function __construct(string $rank)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
$this->rank = $rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param non-empty-string $rank
|
||||||
|
*
|
||||||
|
* @return Result<Rank|string>
|
||||||
|
*/
|
||||||
|
private static function rankValidator(string $rank): Result
|
||||||
|
{
|
||||||
|
if (strlen($rank) > self::MAX_RANK_LEN) {
|
||||||
|
return Error::create('The length of Rank provided is too long. Rank Provided: ' . $rank . ' - Rank Length: ' . strlen($rank) . ' - Max length: ' . self::MAX_RANK_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$invalidChars = array_filter(
|
||||||
|
str_split($rank),
|
||||||
|
static function ($char) {
|
||||||
|
return ord($char) < ord(self::MIN_CHAR) || ord($char) > ord(self::MAX_CHAR);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($invalidChars !== []) {
|
||||||
|
return Error::create('Rank provided contains an invalid Char. Rank Provided: ' . $rank . ' - Invalid char: ' . implode(', ', array_values($invalidChars)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastChar = substr($rank, -1);
|
||||||
|
if ($lastChar === self::MIN_CHAR) {
|
||||||
|
return Error::create('The last char of the rank (' . $rank . ') can\'t be equal to the min char (' . self::MIN_CHAR . ').');
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success::create(new self($rank));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(): string
|
||||||
|
{
|
||||||
|
return $this->rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param non-empty-string $rank
|
||||||
|
*
|
||||||
|
* @return Result<Rank|string>
|
||||||
|
*/
|
||||||
|
public static function fromString(string $rank): Result
|
||||||
|
{
|
||||||
|
return self::rankValidator($rank);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChar(int $i, string $defaultChar): string
|
||||||
|
{
|
||||||
|
return $this->rank[$i] ?? $defaultChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user