-
Notifications
You must be signed in to change notification settings - Fork 2
feat(utils): added merging util #515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 7 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
1a2f306
Moved merging to api
slaveeks ef976ce
fix merge
slaveeks 70d4cc1
rm useless logs
slaveeks 995c181
fix lint
slaveeks 60d22ed
revevert factory changes
slaveeks 027ea78
fix
slaveeks bddcecf
Bump version up to 1.1.30
github-actions[bot] 1c2ad41
use types from lib
slaveeks e3b4d8a
added merge tests
slaveeks 4638a8f
Merge branch 'feat/merging' of github.com:codex-team/hawk.api.nodejs …
slaveeks a6b9f01
fix code style
slaveeks 1690cf8
fix tests
slaveeks 9f6df54
set date
slaveeks File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| import mergeWith from 'lodash.mergewith'; | ||
| import cloneDeep from 'lodash.clonedeep'; | ||
| import { patch } from '@n1ru4l/json-patch-plus'; | ||
|
|
||
| type HawkEvent = { | ||
| payload: { | ||
| [key: string]: any; | ||
| }; | ||
| } | ||
|
|
||
| type HawkEventRepetition = { | ||
| payload: { | ||
| [key: string]: any; | ||
| }; | ||
| delta: string; | ||
| } | ||
|
|
||
| /** | ||
| * One of the features of the events is that their repetition is the difference | ||
| * between the original, which greatly optimizes storage. So we need to restore | ||
| * the original repetition payload using the very first event and its difference | ||
| * between its repetition | ||
| * | ||
| * @param originalEvent - the very first event we received | ||
| * @param repetition - the difference with its repetition, for the repetition we want to display | ||
| * @returns fully assembled payload of the current repetition | ||
| */ | ||
| export function repetitionAssembler(originalEvent: Record<string, any>, repetition: { [key: string]: any }): any { | ||
neSpecc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const customizer = (originalParam: any, repetitionParam: any): any => { | ||
| if (repetitionParam === null) { | ||
| return originalParam; | ||
| } | ||
|
|
||
| if (typeof repetitionParam === 'object' && typeof originalParam === 'object') { | ||
| /** | ||
| * If original event has null but repetition has some value, we need to return repetition value | ||
| */ | ||
| if (originalParam === null) { | ||
| return repetitionParam; | ||
| /** | ||
| * Otherwise, we need to recursively merge original and repetition values | ||
| */ | ||
| } else { | ||
| return repetitionAssembler(originalParam, repetitionParam); | ||
| } | ||
| } | ||
|
|
||
| return repetitionParam; | ||
| }; | ||
|
|
||
| return mergeWith(cloneDeep(originalEvent), cloneDeep(repetition), customizer); | ||
| } | ||
|
|
||
| function parsePayloadField(payload: any, field: string) { | ||
neSpecc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
neSpecc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (payload && payload[field] && typeof payload[field] === 'string') { | ||
| payload[field] = JSON.parse(payload[field]); | ||
| } | ||
|
|
||
| return payload; | ||
| } | ||
|
|
||
| function stringifyPayloadField(payload: any, field: string) { | ||
neSpecc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (payload && payload[field]) { | ||
| payload[field] = JSON.stringify(payload[field]); | ||
| } | ||
|
|
||
| return payload; | ||
| } | ||
|
|
||
| /** | ||
| * Helps to merge original event and repetition due to delta format, | ||
| * in case of old delta format, we need to patch the payload | ||
| * in case of new delta format, we need to assemble the payload | ||
| * | ||
| * @param originalEvent {HawkEvent} - The original event | ||
| * @param repetition {HawkEventRepetition} - The repetition to process | ||
| * @returns {HawkEvent} Updated event with processed repetition payload | ||
| */ | ||
| export function composeFullRepetitionEvent(originalEvent: HawkEvent, repetition: HawkEventRepetition | undefined): HawkEvent { | ||
| /** | ||
| * Make a deep copy of the original event, because we need to avoid mutating the original event | ||
| */ | ||
| const event = cloneDeep(originalEvent); | ||
|
|
||
| if (!repetition) { | ||
| return event; | ||
| } | ||
|
|
||
| /** | ||
| * New delta format (repetition.delta is not null) | ||
| */ | ||
| if (repetition.delta) { | ||
| /** | ||
| * Parse addons and context fields from string to object before patching | ||
| */ | ||
neSpecc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| event.payload = parsePayloadField(event.payload, 'addons'); | ||
| event.payload = parsePayloadField(event.payload, 'context'); | ||
|
|
||
| event.payload = patch({ | ||
| left: event.payload, | ||
| delta: JSON.parse(repetition.delta), | ||
| }); | ||
|
|
||
| /** | ||
| * Stringify addons and context fields from object to string after patching | ||
| */ | ||
| event.payload = stringifyPayloadField(event.payload, 'addons'); | ||
| event.payload = stringifyPayloadField(event.payload, 'context'); | ||
|
|
||
| return event; | ||
| } | ||
|
|
||
| /** | ||
| * New delta format (repetition.payload is null) and repetition.delta is null (there is no delta between original and repetition) | ||
| */ | ||
| if (!repetition.payload) { | ||
| return event; | ||
| } | ||
|
|
||
| /** | ||
| * Old delta format (repetition.payload is not null) | ||
| * @todo remove after July 5 2025 | ||
neSpecc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| */ | ||
| event.payload = repetitionAssembler(event.payload, repetition.payload); | ||
|
|
||
| return event; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.