Compare commits

...

460 Commits

Author SHA1 Message Date
c754dc3471 Merge pull request '0.7.0' (!79) from dev into master
Reviewed-on: #79
2023-11-26 10:08:10 +03:00
8f7d754301 Update gradle 2023-11-26 10:07:39 +03:00
c923c3e7d3 Merge remote-tracking branch 'spc/master' into dev 2023-11-26 10:06:39 +03:00
99b2d941c8 Update Readme and CHANGELOG 2023-11-26 10:05:19 +03:00
191af77f57 0.7.0 2023-11-26 09:59:28 +03:00
79759c5256 Replace MetaProvider::getMeta by get 2023-11-22 17:06:23 +03:00
2eb965e563 Type -> DfId
Add descriptor to MetaConverter
2023-11-18 22:48:10 +03:00
1b29e377ca Type -> DfId
Add descriptor to MetaConverter
2023-11-18 22:43:53 +03:00
2634a19285 deprecate String.parseValue 2023-11-12 14:26:28 +03:00
261c415d3d Meta converters return non-nullables 2023-10-29 21:39:40 +03:00
e52d509c2b Add Name.last extension 2023-10-29 10:48:33 +03:00
706521a6b6 Suppress manual cast warnings in task builders 2023-10-24 10:52:41 +03:00
94000689da Merge branch 'beta/kotlin-1.9.20' into dev
# Conflicts:
#	CHANGELOG.md
#	build.gradle.kts
#	dataforge-workspace/src/jvmMain/kotlin/space/kscience/dataforge/workspace/FileWorkspaceCache.kt
#	dataforge-workspace/src/jvmTest/kotlin/space/kscience/dataforge/workspace/FileDataTest.kt
#	gradle.properties
2023-10-24 09:04:37 +03:00
851fdda311 Fix memory leak in sealed builder. Fine-grained Meta builders. 2023-10-08 18:21:04 +03:00
cbbcd18df3 Refactor io. 2023-10-08 18:20:23 +03:00
dc2bf5da83 Merge branch 'kotlinx-io' into dev
# Conflicts:
#	dataforge-io/build.gradle.kts
#	dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/JsonMetaFormat.kt
#	gradle.properties
2023-10-08 16:55:47 +03:00
f732b85cc5 kotlin 1.9.20 2023-09-16 15:20:31 +03:00
259b882e63 kotlin 1.9.20 2023-09-13 12:19:20 +03:00
526f230300 Merge branch 'kotlinx-io' into beta/kotlin-1.9.20
# Conflicts:
#	dataforge-io/build.gradle.kts
#	dataforge-io/src/commonMain/kotlin/space/kscience/dataforge/io/JsonMetaFormat.kt
#	gradle.properties
2023-09-13 08:28:43 +03:00
SPC-code
7fca5db390
Merge pull request #78 from SciProgCentre/dependabot/github_actions/dot-github/workflows/gradle/gradle-build-action-2.4.2
Bump gradle/gradle-build-action from 2.1.5 to 2.4.2 in /.github/workflows
2023-07-29 13:15:37 +03:00
dependabot[bot]
be160ba98a
Bump gradle/gradle-build-action in /.github/workflows
Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 2.1.5 to 2.4.2.
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](https://github.com/gradle/gradle-build-action/compare/v2.1.5...v2.4.2)

---
updated-dependencies:
- dependency-name: gradle/gradle-build-action
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-29 10:14:01 +00:00
SPC-code
182f206b88
Merge pull request #77 from SciProgCentre/dev
0.6.2
2023-07-29 13:13:38 +03:00
3806f97c77 update documentation 2023-07-29 13:00:17 +03:00
d5ebef404f update documentation 2023-07-29 12:59:55 +03:00
3644533043 update documentation 2023-07-29 12:56:35 +03:00
ee5afcdafe Update meta serialization rules 2023-07-29 12:42:14 +03:00
de476fb273 Fix json serialization. 2023-07-26 16:47:12 +03:00
a136db16ff Refactoring to kotlinx-io complete 2023-07-15 10:49:42 +03:00
a699c36f8e [WIP] Refactoring to kotlinx-io 2023-07-11 23:03:52 +03:00
2aba1b48dc [WIP] Refactoring to kotlinx-io 2023-07-10 10:06:39 +03:00
cfa20eedba Update version to 1.9 2023-07-09 21:38:33 +03:00
SPC-code
f78f0f814f
Create LICENSE 2023-07-02 14:34:52 +03:00
4e7ead0763 Merge remote-tracking branch 'space/master' into dev
# Conflicts:
#	gradle.properties
2023-03-31 14:14:34 +03:00
4543648cda Fix SchemeMeta.attach 2023-03-31 14:00:55 +03:00
b6949310ea Prepare for 0.6.1 release 2023-03-31 09:38:34 +03:00
2c2f33427a Fixes in Envelope format and data tre 2023-03-27 09:45:51 +03:00
29fa30fb51 add type checks for inMemoryCache 2023-03-20 18:34:03 +03:00
f3afb5e9fe File-based workspace caching 2023-03-20 17:53:40 +03:00
61c8df9eb0 Minor update to workspace cache 2023-03-09 10:56:35 +03:00
707b59e6fc Update version 2023-02-24 10:05:01 +03:00
add400b324 Update SPC deployment address 2023-02-20 18:37:24 +03:00
58c5355e25 Fix bug in plugin isAttached 2023-02-20 18:31:56 +03:00
f83b759e75 Optimize Name::cutFirst and Name::cutLast 2023-02-18 19:50:09 +03:00
7d88f828d7 Move to gradle plugin 0.14 2023-02-18 19:49:41 +03:00
5d7ddb4e00 Simplify DFTL. fix io bugs 2023-01-25 18:56:19 +03:00
82838b6a92 Workspace cache 2023-01-08 12:44:31 +03:00
e41fdfc086
Fix naming conventions in names 2023-01-08 11:03:58 +03:00
4117a05df4
Add in-memory caching for workspaces 2022-10-03 20:36:28 +03:00
5406a6a64c
Optimize Name hashCode 2022-08-23 10:58:09 +03:00
0cc4dc0db7
Optimize Name hashCode 2022-08-23 10:55:00 +03:00
233639f0b6
Optimize work with names and tokens 2022-08-22 14:16:16 +03:00
70bd92f019
Add debug level to JS logger 2022-08-14 15:09:51 +03:00
f8eea45ed0
add readOnly to the descriptor 2022-08-13 19:16:18 +03:00
e14c0a695e
fix withDefault 2022-08-11 17:59:31 +03:00
3c1fe23366
Values package merged into meta 2022-08-08 15:09:16 +03:00
81e2ad06cc
refactor MutableMeta set method to accept wider range of receivers 2022-08-01 18:12:57 +03:00
6ca76cff17
Update output types of DataTree builders 2022-07-02 19:34:58 +03:00
9a24e1e392
Update output types of DataTree builders 2022-07-02 12:36:41 +03:00
9cceb44a90
Add NameToket.toStringUnescaped 2022-06-24 18:44:36 +03:00
0b68c1edae
minor API update 2022-06-22 20:00:27 +03:00
b8869570ce
refactor file reading 2022-05-25 19:00:12 +03:00
4833128857
refactor file reading 2022-05-21 11:08:59 +03:00
6bd8a7acbc
return type to IOReader 2022-05-21 10:38:53 +03:00
f5d32ba511
Update build version 2022-05-17 12:24:15 +03:00
0fc2198832
- Remove all unnecessary properties for IOFormat
- Separate interfaces for `IOReader` and `IOWriter`
2022-05-16 18:57:48 +03:00
a546552540
Replace sequences by iterators in DataSet 2022-05-10 14:45:58 +03:00
fe92e8fccf
Data traversal refactoring 2022-05-08 20:56:14 +03:00
7d9189e15c Replace T by Pair<Meta, T> in data reducers 2022-05-07 18:06:55 +03:00
0622bacc4d
Refactor DataSet. Remove suspends where it is possible. 2022-05-04 17:27:56 +03:00
bedab0dc86
Remove experimental flag from YAML 2022-05-03 17:42:00 +03:00
f0820a3bed
Reify types for action builders 2022-05-01 20:23:37 +03:00
665f317e4e
Remove obsolete getData for DataSet 2022-05-01 19:29:13 +03:00
82d37f4b55
Fix text envelope formats partial reads 2022-04-29 18:35:44 +03:00
6d396368b7
Fixe meta file name 2022-04-24 14:44:31 +03:00
77857289f0
DataSet flow to sequence 2022-04-24 09:57:33 +03:00
eaa9d40d60
Change suspend DataSet.getData to operator DataSet.get 2022-04-24 09:19:14 +03:00
6b41163ed3
Fix select.kt 2022-04-17 22:21:11 +03:00
e5000171f1
move to Kotlin 1.6.20 and KTor 2.0 2022-04-17 21:59:09 +03:00
3c6bc15716
move to Kotlin 1.6.20 and KTor 2.0 2022-04-15 18:56:00 +03:00
11143e4ba1
0.5.3-dev-4 2022-03-07 16:12:01 +03:00
91621864c2
add specOrNull delegate 2021-12-18 17:02:17 +03:00
1e97165328
Refactory Factory 2021-12-12 17:58:01 +03:00
Alexander Nozik
be8e971436
all platforms for macos publication 2021-12-12 11:13:35 +03:00
Alexander Nozik
9cc30b1f4e
disable sonatype publishing 2021-12-12 10:48:52 +03:00
Alexander Nozik
7414e60192
Update publish.yml
force disable github publishing
2021-11-30 14:42:00 +03:00
Alexander Nozik
8c0bc05a9a
Merge pull request #74 from mipt-npm/dev
0.5.2
2021-11-30 13:12:20 +03:00
c480cd8e4d
Fix native test 2021-11-30 12:53:52 +03:00
64e0c554cc 0.5.2 release 2021-11-30 11:58:23 +03:00
532e0c253b Add Yaml meta format plugin 2021-11-27 13:36:07 +03:00
c423dc214e Some name refactoring 2021-11-24 20:26:29 +03:00
d178c4ff0d Fix number comparison bug in value 2021-11-02 10:50:38 +03:00
Alexander Nozik
387ab8747e
Merge pull request #72
Kotlin 1.6
2021-10-10 14:38:02 +03:00
3f54eee578 Workaround for https://youtrack.jetbrains.com/issue/KT-48988. Smart building of child contexts 2021-10-10 14:32:32 +03:00
aded38254e Workspace and task updates 2021-10-09 10:49:38 +03:00
00d964eef3 Workspace and task updates 2021-10-08 09:54:11 +03:00
b07d281a83 Kotlin 1.6 2021-09-29 11:08:55 +03:00
81cdd38c40 Build 2021-09-28 12:26:50 +00:00
0ad6852e36 Fix meta node listeners and attachements 2021-08-15 13:20:54 +03:00
a71bb732da Fix meta node listeners and attachements 2021-08-14 18:14:37 +03:00
Alexander Nozik
acfe9c2f74
Merge pull request #70 from mipt-npm/dev
0.5.0
2021-08-13 21:42:32 +03:00
ce8074c104 API dump 2021-08-13 21:00:34 +03:00
922a3b07ee 0.5.0 release 2021-08-13 20:55:05 +03:00
81abbe28a9 Add fast cast for recursive generics 2021-08-11 18:03:06 +03:00
da9d6e7639 Add ValueProvider.kt 2021-08-10 22:41:06 +03:00
66c708d9fb Add ValueProvider.kt 2021-08-10 21:30:40 +03:00
c1065c2885 Fix Scheme special meta implementation 2021-08-10 13:34:59 +03:00
e5f422f9ca Protect meta aquisition in Scheme 2021-08-08 15:29:57 +03:00
c01bc36d41 Laminate refactor 2021-08-07 21:26:58 +03:00
be2daca25e Add force-invalidate to ObservableMeta 2021-08-07 14:06:00 +03:00
b968d735ce Add force-invalidate to ObservableMeta 2021-08-07 13:59:19 +03:00
67554a8c98 Move scheme descriptors to core 2021-08-07 13:41:47 +03:00
24187722e4 Move scheme descriptors to core 2021-08-07 12:02:34 +03:00
d3c129526d tweak MetaDescriptor.kt 2021-08-07 10:42:43 +03:00
5632487dca tweak MetaDescriptor.kt 2021-08-07 10:31:32 +03:00
e432b07201 Descriptor updates and utilities 2021-08-06 12:29:48 +03:00
28a6914747 Empty meta is represented by empty json object 2021-08-01 21:02:15 +03:00
90a92c4121 Don't serialize empty metas 2021-08-01 20:27:43 +03:00
b404615145 Cleanup Json serializers 2021-08-01 19:17:20 +03:00
7aec2f3547 Cleanup delegates. Fix a lot of bugs 2021-08-01 14:28:11 +03:00
3ba5a9076b Change Configurable config name 2021-07-31 17:06:17 +03:00
8763d63e28 Name revolution 2021-07-31 15:02:11 +03:00
4a76063093 add append methods for meta 2021-07-30 19:56:31 +03:00
5fbbac465a fix dynamic meta 2021-07-30 18:05:57 +03:00
b387b21554 WIP fix dynamic meta 2021-07-30 12:00:18 +03:00
c8bd3390cb Cover corner cases in JsonMeta 2021-07-30 09:17:46 +03:00
a3479e74f7 WIP full refactor of Meta 2021-07-25 12:57:10 +03:00
9f5b010847 WIP full refactor of Meta 2021-07-24 19:58:19 +03:00
679175391a Simplify Scheme even more. Add serialization 2021-07-18 16:33:37 +03:00
14455c2b2b Moved tables to a separate project 2021-07-18 14:35:31 +03:00
a9cec666a3 Proper json index for single-value array 2021-07-15 12:10:56 +03:00
d2ea1a975e Refactor ItemProvider hierarchy 2021-07-08 12:16:00 +03:00
73b3bbe7fc Immutable plugin manager 2021-07-08 12:15:34 +03:00
474597777c Relaxed type restriction on MetaConverter 2021-06-23 08:20:22 +03:00
9d3c7149b7 Fix indexed meta to json transformation 2021-06-20 10:29:37 +03:00
bc9cd3b5a8 Merge remote-tracking branch 'origin/dev' into dev 2021-06-04 19:52:55 +03:00
254163bdef Update kotlin version. Minor fix to Meta equality 2021-06-04 19:52:34 +03:00
Alexander Nozik
3bdaf332cb
Merge pull request #67 from mipt-npm/commandertvis/metaspace
Set 2 GB Metaspace size for Gradle build VM
2021-05-26 11:14:32 +03:00
Alexander Nozik
6e769d1089
Merge pull request #68 from mipt-npm/commandertvis/ga
Update GA configurations
2021-05-26 11:14:11 +03:00
Alexander Nozik
e62ff61814
Merge pull request #66 from mipt-npm/commandertvis/table
Documentation for ExposedTable
2021-05-26 11:13:12 +03:00
1037c45c0d Experimental listOfSpec delegate. 2021-05-11 12:43:00 +03:00
82b328f797 Experimental listOfSpec delegate. 2021-05-11 12:42:41 +03:00
a6f1e54255 Update descriptor cache 2021-05-09 22:27:52 +03:00
3888b2d9e7 Merge remote-tracking branch 'origin/dev' into dev 2021-05-09 21:32:28 +03:00
0acb6ec448 Cache descriptor defaults 2021-05-09 21:32:15 +03:00
Iaroslav Postovalov
b616e3ad6d
Update GA configurations 2021-05-09 16:07:24 +07:00
Iaroslav Postovalov
d1381cc98c
Set 2 GB Metaspace size for Gradle build VM 2021-05-09 15:28:15 +07:00
Iaroslav Postovalov
543023d2df
Documentation for ExposedTable 2021-05-09 15:19:07 +07:00
Alexander Nozik
d769b0d389
Merge pull request #65 from CommanderTvis/commandertvis/table
Exposed based Table implementation
2021-05-09 09:28:29 +03:00
Iaroslav Postovalov
3fc698dd09
Exposed based Table implementation 2021-05-09 06:21:02 +07:00
Alexander Nozik
32b986fc47
Merge pull request #64 from mipt-npm/dev
0.4.0
2021-04-27 11:23:43 +03:00
3e8421187f patach CHANGELOG.md 2021-04-27 11:17:27 +03:00
5afe0523f1 refactor to kotlin 1.5 2021-04-27 10:55:58 +03:00
a7ecbfb763 Update changelog 2021-04-11 11:24:25 +03:00
2352f1cff1 Split ItemDescriptor to builder and read-only descriptor 2021-04-11 11:15:25 +03:00
1a983665f8 Fix useProperty type 2021-04-08 13:50:43 +03:00
53393e7958 Cleaup context building API 2021-04-07 18:47:24 +03:00
874a253292 Fix property usage for ObservableItemProvider 2021-04-07 15:34:27 +03:00
187094d942 Kotlin 1.5. Further context plugins readOnlyZation 2021-04-07 11:39:24 +03:00
23f1d4f7fd Add item property listeners and item property binding tests 2021-04-06 17:19:24 +03:00
f1f5f7a70c Isolate and deprecate Context plugin mutation logic. 2021-04-06 15:12:40 +03:00
9fbc482549 Scheme made observable 2021-04-05 22:01:09 +03:00
Alexander Nozik
b86c6141cd
Merge pull request #62 from mipt-npm/dev
Publishing settings
2021-03-07 15:43:34 +03:00
ddd2bd99be Publishing settings 2021-03-07 15:23:59 +03:00
Alexander Nozik
e13e3ab6bf
Merge pull request #61 from mipt-npm/dev
0.4.0-dev-2
2021-03-07 15:06:32 +03:00
bdef0d9185 Publishing settings 2021-03-07 15:05:36 +03:00
6bdcd0f37d Use slf4j API instead of logback 2021-03-07 09:46:01 +03:00
18bfde9978 Fix deploy to space 2021-03-05 19:27:13 +03:00
64100dcfe4 readme update 2021-03-03 22:41:33 +03:00
3f0d088c48 Change package name to space.kscience 2021-03-03 11:36:22 +03:00
b6dad141f8 Fix log loading 2021-03-01 10:25:02 +03:00
f3d43cd40a Remove kotlinx-io 2021-02-28 22:03:40 +03:00
c98ffd1eb4 Logging refactor. Remove Kotlin-logging from common 2021-02-28 11:45:19 +03:00
488cd5a939 Tables refactor to KType 2021-02-23 17:40:28 +03:00
cf0c934acf Move logging to implementation 2021-02-23 17:40:05 +03:00
Alexander Nozik
a7ee2f5922
Merge pull request #60 from mipt-npm/dev
0.3.0
2021-02-07 21:18:04 +03:00
a726307641 Update Readme 2021-02-07 20:58:43 +03:00
db4ed02f9d Update Readme 2021-02-07 20:58:19 +03:00
2b945d4a78 Update CHANGELOG.md 2021-02-07 20:49:48 +03:00
Alexander Nozik
f6210fde7f
Merge pull request #59 from mipt-npm/refactor/data-types
Refactor/data types
2021-02-07 20:37:40 +03:00
5d02520904 turn on API validation 2021-02-07 20:23:33 +03:00
7d3df24568 Remove KClass from dataforge-data 2021-02-07 19:36:41 +03:00
1970243785 Remove KClass from dataforge-data 2021-02-07 18:15:54 +03:00
03337f00f0 Merge branch 'dev' into refactor/data-types 2021-02-07 12:46:28 +03:00
81fb064d38 Maturity declarations. 2021-02-07 12:46:15 +03:00
730ac69544 build tools 0.7.5 and JVM-IR 2021-02-05 09:49:35 +03:00
fcd99b1ca8 [WIP] change KClass to KType 2021-02-02 17:48:25 +03:00
6a0bfae931 minor data refactor 2021-02-02 12:09:44 +03:00
11ba116a89 Update DataSetBuilder API 2021-01-31 22:37:32 +03:00
4d19d97c53 Update DataSetBuilder API 2021-01-31 22:34:48 +03:00
e66ae408cd Fix return type for ActiveDataTree.kt 2021-01-31 20:55:01 +03:00
0e053ab78d Move yaml to multiplatform 2021-01-30 19:49:28 +03:00
66355793ee Remove restriction on empty ListValue since it have a separate type now. 2021-01-28 10:34:28 +03:00
e88178ffe7 readEnvelopeFile throws exception instead of returning null for missing encoders 2021-01-28 10:25:54 +03:00
25cba0c6de bump version to 0.3.0-dev-1 2021-01-26 18:26:28 +03:00
2291072e26 Cleanup after task refactoring 2021-01-26 16:13:31 +03:00
80d3a64cdf Gradle to 6.8.1 2021-01-26 15:16:18 +03:00
9dacd98f64 Full Workspace and data refactor 2021-01-26 15:11:12 +03:00
366d32a04a Name matching 2021-01-24 22:11:25 +03:00
ac8631e3a0 [WIP] redo Workspace 2021-01-17 19:11:49 +03:00
7e4d1af55f [WIP] redo DataSet fill and updates 2021-01-16 12:44:39 +03:00
3334380693 Add toString to Path 2021-01-12 18:34:25 +03:00
b916a038f7 WIP full data refactor 2021-01-10 18:18:34 +03:00
23fae9794f WIP full data refactor 2021-01-10 17:46:53 +03:00
9ed4245d84 WIP full data refactor 2021-01-10 14:32:52 +03:00
13c0d189bb Move DataNode builders 2020-12-30 09:56:49 +03:00
8b1d5eb69e Task and data input validation moved to JVM 2020-12-29 22:19:11 +03:00
030f3ed6fe Refactor context factories 2020-12-28 21:05:27 +03:00
027d5ed923 Fix scheme wrapping 2020-12-27 17:40:34 +03:00
f946777f40 Add retarget method to change the target of a Scheme 2020-12-26 13:34:53 +03:00
7a9f7da7f2 Scheme empty check moved to extension 2020-12-26 10:35:24 +03:00
81375d4644 Separate ReadOnlySpecification. Cleanup Scheme inflation 2020-12-25 19:27:58 +03:00
9c3f9420ea cleanup specification. again 2020-12-25 18:28:23 +03:00
adf65a5bde Fix Specification update 2020-12-25 16:43:39 +03:00
460dc77d51 Fix MetaItem inference from Any 2020-12-25 16:19:19 +03:00
76968f07e5 Fix scheme initialization 2020-12-24 23:17:32 +03:00
6389a25aaf Moved ValueItem and NodeItem to the top level 2020-12-24 10:48:51 +03:00
1c89543d73 Cleanup 2020-12-24 10:32:11 +03:00
397a19fb32 Cleanup 2020-12-24 09:48:14 +03:00
e931994b75 Cleanup 2020-12-23 21:22:47 +03:00
617ed13efa fix imports 2020-12-23 19:15:47 +03:00
89f0d627b8 A major refactor MutableItemProvider instead of Config 2020-12-23 19:09:02 +03:00
702589f7b3 add copy method to descriptors 2020-12-20 18:22:50 +03:00
1f773cc230 Config API change 2020-12-19 20:54:55 +03:00
95e6925d55 bump api 2020-12-13 23:09:53 +03:00
62e08a1b75 Refactor Value::toString 2020-12-13 23:00:58 +03:00
18407424fe Merge remote-tracking branch 'origin/dev' into dev 2020-12-13 22:59:13 +03:00
4c5f0e9e43 Add synchronization to Config listeners 2020-12-13 19:58:20 +03:00
7c4d69ec1b Refactor Value. 2020-12-09 12:04:10 +03:00
e317b67a48 Api dump and import fixes 2020-12-04 17:56:33 +03:00
2ba4121a36 Logging moved to extensions 2020-12-04 17:34:12 +03:00
eb16294a7e Fix api definitions 2020-12-04 14:07:00 +03:00
17c9bf3d54 Move envelope builder to the top level. 2020-12-04 11:26:03 +03:00
221cc65b78 Meta builder made inline 2020-12-04 11:20:20 +03:00
2098d96561 Fix build and update internals of MetaSerializer 2020-12-04 10:38:56 +03:00
4c98d62e8f Implement YamlMetaFormat with yaml.kt 2020-12-04 10:19:42 +03:00
47d49d1e0e Minor change to meta serialization descriptors 2020-12-03 13:35:19 +03:00
1b46d00a91 Changed the logic of Value::isList for serialization 2020-11-29 10:18:52 +03:00
Alexander Nozik
6912f26291
Merge pull request #58 from mipt-npm/dev
0.2.0 release
2020-11-28 10:29:09 +03:00
2315fb963b Patch changelog 2020-11-26 22:21:29 +03:00
3a6aef95b1 Bump version 2020-11-26 22:20:25 +03:00
167b73df85 0.2.0 - RC 2020-11-25 22:18:39 +03:00
2eb5fe03cd Fix scheme initialization 2020-11-20 16:58:27 +03:00
0a77f729ec Fixed inline invloke on Specification 2020-11-20 14:47:18 +03:00
920366388d Changelog update 2020-11-13 19:44:07 +03:00
1284aa9f2e Configurable is no longer MutableItemProvider. All functionality moved to Scheme 2020-11-11 13:37:02 +03:00
d68fbfd8a5 Descriptor in SchemeSpec 2020-11-11 10:54:52 +03:00
3ab3f2766c Add preemptive initialization for plugins 2020-11-10 20:18:54 +03:00
d5992c721d Refactor Scheme and MutableItemProvider.kt 2020-11-10 19:08:53 +03:00
8ef0b2247c Changed kotlin version to 1.4.20-M2 2020-10-28 13:01:29 +03:00
c0348dd06f Merge remote-tracking branch 'origin/dev' into dev 2020-10-17 17:22:59 +03:00
d6ed5f94e4 Removed IO dependency from Output 2020-10-17 17:22:34 +03:00
Mikhail Zelenyi
ccb11b52c8
Update Scheme.kt
Add default empty block.
2020-10-13 07:59:57 +03:00
01c209d1d6 Finish migration to 1.4.20 2020-09-28 15:38:29 +03:00
acfb070938 New Meta serializer 2020-09-16 15:10:43 +03:00
810f79b9ed Merge branch 'dev' into kotlin-1.4.20
# Conflicts:
#	settings.gradle.kts
2020-09-15 21:15:13 +03:00
44ef4ad97f bump version 2020-09-15 21:14:21 +03:00
bc4456637c Native for all 2020-09-14 20:32:41 +03:00
4ab9751bea Commented fake overrides in Meta to work around KT-41765 2020-09-13 20:06:09 +03:00
b229de3eb7 Context content resolution refactor.
Explicit API mode.
2020-09-13 19:35:58 +03:00
7658839acf Merge branch 'dev' into kotlin-1.4.20 2020-09-09 10:23:27 +03:00
d170f5d60c Explicit API mode 2020-09-09 10:22:15 +03:00
fed787331d Kotlin 1.4.20-dev 2020-09-09 10:21:16 +03:00
606faa5e1b Explicit mode 2020-09-08 21:45:50 +03:00
8a8484172c Fix IO after refactoring 2020-09-08 16:04:15 +03:00
52a3c8bc6f dataforge-meta cleanup 2020-09-07 22:43:39 +03:00
87af89b47d Refactor MetaItem delegates. 2020-09-07 16:19:57 +03:00
eeb4643d93 IO refactoring 2020-09-07 13:44:02 +03:00
a767f279a3 Fixed 1.4 build 2020-09-05 16:19:03 +03:00
b7d01bc40f Using dev plugin 2020-09-02 12:11:44 +03:00
99fee604d8 HTML renderer refactoring 2020-08-31 12:39:44 +03:00
6ad5f162a1 Refactor Name and NameToken. Breaking change 2020-08-31 12:02:06 +03:00
57b263ec63 Migration to 1.4 2020-08-31 11:27:44 +03:00
b8d775aa30 Migration to 1.4 2020-08-29 11:45:31 +03:00
617612bf67 Add default implementation to the provider. 2020-08-15 20:33:39 +03:00
b5b0a6898e Add default implementation to the provider. 2020-07-26 17:36:18 +03:00
34110f6be1 Remove function clients and servers 2020-07-26 17:35:44 +03:00
b72f73f75b Remove needless item delegate 2020-07-26 17:34:35 +03:00
4fde6c4a48 Replace missing query by null in NameToken 2020-07-26 15:00:03 +03:00
c3d4836a11 Default error for Provider 2020-07-26 10:23:51 +03:00
8529c725e7 Add more number delegates for read-only items. 2020-07-06 15:02:04 +03:00
Alexander Nozik
d951668911
Merge pull request #52 from mipt-npm/dev
0.1.8
2020-07-05 15:32:13 +03:00
fcba27cd72 Tools to 0.5.1 2020-07-05 15:22:40 +03:00
c280671e61 Yet another refactor of Meta and Configurable delegates (let's hope it is final) 2020-07-05 12:54:27 +03:00
faeb737672 Correct meta item index representation in JSON 2020-07-03 20:38:19 +03:00
87326d05c7 Row type fix 2020-06-24 16:01:36 +03:00
059ade7973 Table refactoring 2020-06-24 14:40:55 +03:00
73fbe19fed Commend some irrelevant parts of README.md 2020-06-07 17:23:50 +03:00
8fc332d42e Merge remote-tracking branch 'origin/master' into dev 2020-06-07 17:21:51 +03:00
Alexander Nozik
f5b2b4c9e4
Merge pull request #51 from mipt-npm/dev
0.1.8-dev-4
2020-06-06 21:28:42 +03:00
9d54358307 Update gradle wrapper to 6.5 2020-06-06 21:10:02 +03:00
086fcd441b Fix MetaItem equality 2020-06-05 21:08:41 +03:00
Alexander Nozik
b5967902cb
Merge pull request #50 from mipt-npm/dev
0.1.8-dev-2. Fix build
2020-05-17 20:22:03 +03:00
fc0454d339 0.1.8-dev-2. Fix build 2020-05-17 20:20:20 +03:00
Alexander Nozik
90a241ac75
Merge pull request #49 from mipt-npm/dev
0.1.8-dev-2
2020-05-17 20:14:06 +03:00
fb559f4562 0.1.8-dev-2 2020-05-17 20:12:44 +03:00
453a1bc755 Remove reflection from common module 2020-04-22 13:40:35 +03:00
5e8e3014f7 Node editor for MutableMeta 2020-04-21 19:32:29 +03:00
aa52c45c5a Fix boolean value toString() 2020-04-19 23:13:00 +03:00
fb28c854b3 Fix structured concurrency in Context 2020-04-17 18:31:22 +03:00
7c68fc6e85 add test to descriptor default 2020-04-13 16:10:46 +03:00
0434360d46 Cleanup type variance in Task builder 2020-04-13 15:34:26 +03:00
f67fb63c45 Fix for #48 2020-04-13 15:23:05 +03:00
Alexander Nozik
572e5eea60
Merge pull request #46 from mipt-npm/dev
0.1.7
2020-04-08 09:53:22 +03:00
b0950f8415 0.1.7 release 2020-04-07 12:53:00 +03:00
6450696157 Fix zip writer and name refactoring 2020-04-06 22:50:51 +03:00
eebfe534cc Fix Envelope IO with binaries 2020-04-05 21:12:56 +03:00
7efa19920b Migrate to io-dev-6 2020-04-03 12:10:24 +03:00
56e7d55450 Add a Config generator to MetaTransformation 2020-03-28 21:23:44 +03:00
01711c2b8c Move scheme to root meta package to avoid import clutter 2020-03-28 10:25:24 +03:00
7f0ad68d9d Meta to JSON SNS fix 2020-03-28 10:04:59 +03:00
66cee2d42b Specification invoke made inline 2020-03-26 21:11:23 +03:00
5c3d51de58 Fix enum delegate bug (KT-37503) 2020-03-25 19:06:08 +03:00
e0aab57953 Indexed access test 2020-03-25 18:52:58 +03:00
417c292507 Refactor inner workings of descriptors 2020-03-25 10:41:27 +03:00
Alexander Nozik
7dde03ee68
Merge pull request #41 from mipt-npm/dev
0.1.5
2020-03-25 09:07:21 +03:00
e835d81183 Utility methods to access Configurable properties 2020-03-16 22:52:54 +03:00
bc8878da48 Remove redundant cast in tables 2020-03-15 13:45:24 +03:00
b78fc2e7d7 bump version 2020-03-15 13:34:13 +03:00
2c52e9aaa3 Workaround for enum delegate 2020-03-15 13:33:20 +03:00
4ab71a79db Fix meta serialization 2020-03-15 09:22:08 +03:00
db03dfaae9 Finish migrating to 0.4.0 plugin 2020-03-13 19:15:37 +03:00
e2845f4efc Move Meta serialization to dataforge-meta 2020-03-11 22:30:29 +03:00
93c806c3bf Basic design for external connectors 2020-03-02 19:17:36 +03:00
a2e8d4f018 Basic design for property builders 2020-02-22 22:02:58 +03:00
8dfd56f02e Initial API 2020-02-17 14:46:03 +03:00
dfea68b65c Text tables test working 2020-02-16 15:18:09 +03:00
cd4f07267b Mutable tables 2020-02-10 21:49:53 +03:00
126e59f81a Bottom type check for tables 2020-02-08 22:01:56 +03:00
061c570407 API for tables 2020-02-08 21:36:27 +03:00
819ab3ab20 Fix scheme to meta transformation 2020-01-29 21:50:49 +03:00
f906fbdb0a Tables basics
A lot of refactoring
2020-01-29 21:34:51 +03:00
fe6760eee6 Refactor Meta delegates 2020-01-10 11:14:18 +03:00
b83821af51 Configurable and Scheme revision 2020-01-08 21:41:27 +03:00
736ec621b0 Invoke mechanism for defining specific and fix to attach config child 2019-12-28 21:24:16 +03:00
1b879eccc7 Specialized non-null delegates for spec 2019-12-28 16:06:32 +03:00
e532e8358e Remove name from descriptors. It is never used 2019-12-24 22:10:48 +03:00
ce8be78549 Replace EmptyName by Name.Empty
Composite builders for node descriptor
2019-12-24 20:59:14 +03:00
659fded3a5 Replace scecification builders by invokations 2019-12-24 20:06:16 +03:00
f9ae9348e2 Meta subtyping and get by empty name. 2019-12-22 20:30:47 +03:00
effac131de Fix name comparison 2019-12-22 20:29:58 +03:00
be2bca24b1 Build migration 2019-12-22 20:29:32 +03:00
4eb07949b4 Bump build and io versions 2019-12-10 17:15:20 +03:00
0ec42689d7 Minor change to Goal API 2019-12-03 17:01:56 +03:00
c789dabdae Fix build with new IO 2019-12-01 20:53:32 +03:00
ab47d7723e All tests running 2019-12-01 19:46:53 +03:00
ad2f5681b6 Fix everything bu function server 2019-12-01 18:13:10 +03:00
76e7f47528 fix envelope formats 2019-12-01 15:00:27 +03:00
2e643287ef Moving to io-2 2019-11-30 23:36:06 +03:00
45a5b6fe28 Working on zip and directory storage for data. Update to build 0.2.4 2019-11-17 22:15:29 +03:00
38360e9d22 Merge remote-tracking branch 'origin/master' into dev 2019-11-15 21:29:59 +03:00
Alexander Nozik
56334896b8
Create gradle.yml 2019-11-15 21:25:57 +03:00
4370a66164 Fixed TaglessEnvelopeFormat resolution 2019-11-13 21:12:19 +03:00
d10bd40763 Remove use of direct Input to ByteArray conversions due to bugs in kotlinx.io. 2019-11-13 18:24:33 +03:00
41d0cdb2b1 Fix large buffers IO. A lot of refactoring. 2019-11-13 18:08:48 +03:00
3e9cb3915c Meta and Evelope format factories now implement Meta and Envelope formats (default representation). 2019-11-10 19:08:32 +03:00
ff59c14c17 Minor fix to multipart envelope 2019-11-05 21:42:29 +03:00
5265c0e5ab Implements Envelope parts
An envelope consisting of other envelopes
2019-11-05 21:36:17 +03:00
f63a2b6e93 Some serialization fixes 2019-11-05 19:45:53 +03:00
Alexander Nozik
5dc7929475
Merge pull request #23 from mipt-npm/dev
0.1.4
2019-11-01 21:27:52 +03:00
aefee64581 optional descriptor for descriptor builder 2019-11-01 21:15:55 +03:00
33b1de2865 Optimized EnvelopeFormat generation API 2019-11-01 20:04:11 +03:00
6f341f705a Added DF02 format to TaggedEnvelopeFormat. 2019-11-01 19:47:03 +03:00
257601d945 Changed parameter order in ActionEnv 2019-11-01 14:53:58 +03:00
592f911db7 Changed map and reduce action API to include both meta from data and meta from task/action 2019-11-01 14:41:16 +03:00
6e98bc7408 Added descriptors to custom serializers 2019-10-31 10:21:52 +03:00
0ef0a43077 Added check for file size in FileBinary 2019-10-30 19:57:03 +03:00
33c8e7088e Fixed leaked byte packets in io 2019-10-30 19:43:26 +03:00
ade4eec96e Make putted values optional in MetaBuilder 2019-10-30 17:13:31 +03:00
84c5f6d925 Version to 0.1.4 2019-10-29 21:24:45 +03:00
Alexander Nozik
2b1fbf15ea
Merge pull request #22 from mipt-npm/dev-zelenyy
Dev zelenyy
2019-10-29 21:20:39 +03:00
245b5ebc52 Fix #16 2019-10-29 21:20:14 +03:00
dce9199b78 #18 2019-10-29 20:21:38 +03:00
10de05240c Fix #12 2019-10-29 20:11:57 +03:00
264ed14cf4 Fixed array representation in DynamicMeta 2019-10-29 18:45:24 +03:00
04e9601def Fixed array representation in DynamicMeta 2019-10-29 18:20:05 +03:00
728da96eff Front matter envelope format 2019-10-28 19:37:15 +03:00
6cfaac74ae Merge branch 'dev' into feature/yaml
# Conflicts:
#	dataforge-io/dataforge-io-yaml/build.gradle.kts
2019-10-28 12:37:04 +03:00
cd4736ab5e Transformation of Meta to Map and back 2019-10-28 12:35:19 +03:00
3147016bb3 Yaml feature 2019-10-28 10:31:37 +03:00
d3dd15884c Fixed all IO issues (for now) 2019-10-27 16:50:05 +03:00
Mikhail Zelenyy
956c07e386 Fixed default regex in DataFilter 2019-10-22 14:24:22 +03:00
Mikhail Zelenyy
26f5114e48 Simple test for selecting data 2019-10-21 16:26:47 +03:00
87ae41886b Partial TaglessEnvelopeFormat 2019-10-20 19:30:51 +03:00
e686501662 TaglessEnvelopeFormat implementation 2019-10-20 17:57:43 +03:00
bf787fb5fc Added peek format functionality to EnvelopeFormat 2019-10-19 14:36:13 +03:00
44a34eee40 Refactored IO logic 2019-10-19 13:35:50 +03:00
23a2d29e84 Upgraded plugin and added test for data gathering in workspace. 2019-10-09 19:10:37 +03:00
156a43d4bf Fixed enum delegate 2019-10-07 13:27:54 +03:00
3ff3a5d09e Fixed function server 2019-10-07 13:22:44 +03:00
Alexander Nozik
6d52db311d
Merge pull request #20 from Zelenyy/dev-zelenyy
Two test for checking Meta.enum extension.
2019-10-07 12:06:31 +03:00
e3e9412cb6 Fixed build and nasty bug in data builder 2019-10-04 20:23:02 +03:00
Mikhail Zelenyy
e68e184fb2 Two test for checking Meta.enum extension.
Test `testEnum` failed.
2019-10-04 20:16:34 +03:00
1b118986f5 Value extensions to access primitives 2019-10-02 13:48:04 +03:00
337401f6e0 Task builder for WorkspacePlugin 2019-09-24 17:35:06 +03:00
71536051aa Data and DataNode file io update 2019-09-18 16:36:35 +03:00
Alexander Nozik
5423dd2a3d
Update README.md 2019-09-17 08:54:30 +03:00
6c1c49d15e Added strong typing to tasks and task dependencies 2019-09-14 16:50:25 +03:00
c175dc7de4 Added strong typing to tasks and task dependencies 2019-09-14 10:36:47 +03:00
a0abb99d88 A test for complex task logic 2019-09-12 16:53:57 +03:00
74b5a1ac50 Test for node builder. Fixed bug with node content resolve by name 2019-09-12 16:04:22 +03:00
530b1c1b76 Moved TaskBuilder to common. 2019-09-12 11:10:15 +03:00
61c2530c91 Moved TaskBuilder to common. 2019-09-12 10:39:19 +03:00
c239abe6e8 Added unsafe data casts for all platforms and safeCast for JVM 2019-09-11 23:03:56 +03:00
352b98be9b Added unsafe data casts for all platforms and safeCast for JVM 2019-09-11 22:44:56 +03:00
b730d49e6e Convenience methods to access DataNode elements 2019-09-11 20:43:55 +03:00
c44e004495 Envelope client-sever EAP 2019-09-09 16:15:35 +03:00
10b8385324 Named return Name instead of String 2019-09-08 15:11:46 +03:00
8bac218715 Working on remote function call 2019-09-04 22:22:29 +03:00
418e1c2134 Refactored TaskBuilder to be more predictable 2019-09-04 09:50:56 +03:00
7045f34c2c Updated to build plugin 0.1.6 2019-09-02 19:08:28 +03:00
62916d0c67 Name and serialization fix 2019-08-19 22:42:08 +03:00
Alexander Nozik
632cc8dd9c
Merge pull request #15 from mipt-npm/dev
0.1.3
2019-08-17 17:11:48 +03:00
d16d051a1c 0.1.3 release 2019-08-17 17:10:40 +03:00
27c510f5d0 Removed inline from Name due to problems with equality and serialization. 2019-08-17 10:32:58 +03:00
578b4ede21 Meta and Name serialization tests 2019-08-16 16:30:10 +03:00
58a0584cae Compatibility for Json top level arrays and nested arrays added. 2019-08-16 15:08:56 +03:00
8c32eaeb6b Binary and file data update 2019-08-11 18:35:03 +03:00
a8c9100539 Fixed scripting test by randomly placing random strings in random places 2019-08-10 17:51:58 +03:00
d1061a6669 Fix for value equality in JS 2019-08-10 17:28:27 +03:00
56679cff23 Major rework of IO 2019-08-09 20:53:08 +03:00
5921556254 Reworked Data and Goal mechanics 2019-08-09 16:31:59 +03:00
43c18bcde7 Some refactoring in goal mechanics 2019-08-07 22:07:36 +03:00
65633bbd0d Build passes, but a lot of tests fails. Need more work. 2019-08-07 21:14:20 +03:00
72954a8370 Meta equality for all 2019-08-07 20:41:27 +03:00
1f0a317cd8 Complete refactoring of goals and DataNodes 2019-08-07 19:28:44 +03:00
44737faa26 A lot of minor fixes 2019-08-07 11:38:25 +03:00
a729d27d1c Meta serialization update 2019-08-02 15:42:45 +03:00
c82eda28d8 Minor updates for mutable meta and builder 2019-07-31 16:22:14 +03:00
9f6d53f214 Some additional fixes 2019-07-27 17:45:14 +03:00
efddfa8e91 Meta and io fixes 2019-07-27 17:02:48 +03:00
da4a9ebe9d Simplified Provider API 2019-07-05 18:49:36 +03:00
5b053d60a2 optimize plugin loading API 2019-07-02 13:17:41 +03:00
167dc752ea Few more updates for context builder 2019-06-30 14:13:45 +03:00
1722a7dd82 Slightly modified plugin lookup 2019-06-30 10:34:15 +03:00
b13d980c02 migrating to common toolset 2019-06-28 16:28:54 +03:00
3bf49d3fae Isolating build logic 2019-06-28 10:19:58 +03:00
7f95dcf02c Build fix for module deploy 2019-06-22 15:33:33 +03:00
b275288c55 Moved to 1.3.40 and plugin-based build. Fix fo Styled. 2019-06-22 14:29:37 +03:00
535e877eb0 Fixed mpp deploy to artifactory 2019-06-13 09:52:24 +03:00
4ae1f71a05 Fixed value delegate nullability bug. 2019-06-12 21:12:54 +03:00
c6c4509d6c Fixed bug with meta value removal 2019-06-12 19:45:57 +03:00
4bb95ca793 Joined descriptors 2019-06-10 20:07:40 +03:00
07ff982d08 Added common ancestor to descriptors 2019-06-09 18:48:26 +03:00
4e6cf3e785 bump version to 0.1.3-dev-2 2019-06-01 20:30:47 +03:00
846ad4582f MetaTransformation update 2019-06-01 20:21:19 +03:00
d08e1ee57d Optimized type projections in meta. Set operations are now non-generic 2019-06-01 16:04:45 +03:00
f0413464a3 Name comparison 2019-06-01 08:14:37 +03:00
59c46344fa Simplified mutable meta hierarchy 2019-05-28 19:24:23 +03:00
cffb02d483 fixed FileBinary 2019-05-28 18:56:22 +03:00
65a5379f4a build fix 2019-05-28 17:59:55 +03:00
13c5a579ed Envelope IO 2019-05-26 22:05:20 +03:00
7c38cadddd Envelope IO 2019-05-23 22:16:34 +03:00
54c7b55bc4 Working on meta transformations 2019-05-19 21:42:56 +03:00
343ba84118 Introduced a WorkspacePlugin to access tasks from plugin easily 2019-05-19 10:14:49 +03:00
2a395f8064 Test for plugin task loading 2019-05-19 10:05:21 +03:00
f1692297b8 Minor delegates optimization 2019-05-18 11:12:41 +03:00
fdd5b11370 Configurable updater fix 2019-05-10 19:53:54 +03:00
1344471f40 build fix 2019-05-10 09:51:31 +03:00
7daeedb9ff Fixed build for publish 2019-05-09 22:05:23 +03:00
e239a77223 Fixing build for publish (not yet) 2019-05-09 19:42:39 +03:00
288 changed files with 15954 additions and 6304 deletions

41
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,41 @@
name: Gradle build
on:
push:
branches: [ dev, master ]
pull_request:
jobs:
build:
strategy:
matrix:
os: [ macOS-latest, windows-latest ]
runs-on: ${{matrix.os}}
timeout-minutes: 40
steps:
- name: Checkout the repo
uses: actions/checkout@v2
- name: Set up JDK 11
uses: DeLaGuardo/setup-graalvm@4.0
with:
graalvm: 21.2.0
java: java11
arch: amd64
- name: Cache gradle
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Cache konan
uses: actions/cache@v2
with:
path: ~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build
run: ./gradlew build --build-cache --no-daemon --stacktrace

31
.github/workflows/pages.yml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Dokka publication
on:
workflow_dispatch:
release:
types: [ created ]
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 40
steps:
- uses: actions/checkout@v3.0.0
- uses: actions/setup-java@v3.0.0
with:
java-version: 11
distribution: liberica
- name: Cache konan
uses: actions/cache@v3.0.1
with:
path: ~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- uses: gradle/gradle-build-action@v2.4.2
with:
arguments: dokkaHtmlMultiModule --no-parallel
- uses: JamesIves/github-pages-deploy-action@v4.3.0
with:
branch: gh-pages
folder: build/dokka/htmlMultiModule

50
.github/workflows/publish.yml vendored Normal file
View File

@ -0,0 +1,50 @@
name: Gradle publish
on:
workflow_dispatch:
release:
types: [ created ]
jobs:
publish:
environment:
name: publish
strategy:
matrix:
os: [ macOS-latest, windows-latest ]
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3.0.0
- uses: actions/setup-java@v3.10.0
with:
java-version: 11
distribution: liberica
- name: Cache konan
uses: actions/cache@v3.0.1
with:
path: ~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Publish Windows Artifacts
if: matrix.os == 'windows-latest'
uses: gradle/gradle-build-action@v2.4.2
with:
arguments: |
publishAllPublicationsToSpaceRepository
-Ppublishing.targets=all
-Ppublishing.space.user=${{ secrets.SPACE_APP_ID }}
-Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }}
- name: Publish Mac Artifacts
if: matrix.os == 'macOS-latest'
uses: gradle/gradle-build-action@v2.4.2
with:
arguments: |
publishMacosX64PublicationToSpaceRepository
publishMacosArm64PublicationToSpaceRepository
publishIosX64PublicationToSpaceRepository
publishIosArm64PublicationToSpaceRepository
publishIosSimulatorArm64PublicationToSpaceRepository
-Ppublishing.targets=all
-Ppublishing.space.user=${{ secrets.SPACE_APP_ID }}
-Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }}

3
.gitignore vendored
View File

@ -6,5 +6,4 @@ out/
build/
!gradle-wrapper.jar
gradle.properties
!gradle-wrapper.jar

217
CHANGELOG.md Normal file
View File

@ -0,0 +1,217 @@
# Changelog
## Unreleased
### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security
## 0.7.0 - 2023-11-26
### Added
- Obligatory `type: KType` and `descriptor` property for `MetaConverters`
- Added separate `Meta`, `SealedMeta` and `ObservableMutableMeta` builders.
### Changed
- Meta converter `metaToObject` returns a non-nullable type. Additional method `metaToObjectOrNull` for nullable return.
- Kotlin 1.9.20.
- Migrated from ktor-io to kotlinx-io.
- `MutableMeta` builder now returns a simplified version of meta that does not hold listeners.
- More concise names for read/write methods in IO.
- Remove unnecessary confusion with `get`/`getMeta` by removing `getMeta` from the interface.
### Deprecated
- `String.parseValue` is replaced with `Value.parse`
### Fixed
- Memory leak in SealedMeta builder
## 0.6.2 - 2023-07-29
### Changed
- Meta to Json serializer now serializes a single item with index as an array. It is important for plotly integration.
- Meta to Json serializes Meta without children a value as literal or array instead of an object with `@value` field.
## 0.6.1 - 2023-03-31
### Added
- File cache for workspace
- Smart task metadata transformation for workspace
- Add `readOnly` property to descriptors
- Add `specOrNull` delegate to meta and Scheme
- Suspended read methods to the `Binary`
- Synchronously accessed `meta` to all `DataSet`s
- More fine-grained types in Action builders.
### Changed
- `Name::replaceLast` API
- `PluginFactory` no longer requires plugin class
- Collection<Named> toMap -> associateByName
- Simplified `DFTL` envelope format. Closing symbols are unnecessary. Properties are discontinued.
- Meta `get` method allows nullable receiver
- `withDefault` functions do not add new keys to meta children and are consistent.
- `dataforge.meta.values` package is merged into `dataforge.meta` for better star imports
- Kotlin 1.8.20
- `Factory` is now `fun interface` and uses `build` instead of `invoke`. `invoke moved to an extension.
- KTor 2.0
- DataTree `items` call is blocking.
- DataSet `getData` is no longer suspended and renamed to `get`
- DataSet operates with sequences of data instead of flows
- PartialEnvelope uses `Int` instead `UInt`.
- `ActiveDataSet` renamed to `DataSource`
- `selectOne`->`getByType`
- Data traversal in `DataSet` is done via iterator
- Remove all unnecessary properties for `IOFormat`
- Separate interfaces for `IOReader` and `IOWriter`
### Deprecated
- Context.fetch -> Context.request
### Fixed
- `readDataDirectory` does not split names with dots
- Front matter reader does not crash on non-UTF files
- Meta file name in readMeta from directory
- Tagless and FrontMatter envelope partial readers fix.
## 0.5.2
### Added
- Yaml plugin
- Partial fix to #53
### Fixed
- MutableMetaImpl attachment and checks
- Listeners in observable meta are replaced by lists
- JS number comparison bug.
## 0.5.0
### Added
- Experimental `listOfSpec` delegate.
### Changed
- **API breaking** Config is deprecated, use `ObservableMeta` instead.
- **API breaking** Descriptor no has a member property `defaultValue` instead of `defaultItem()` extension. It caches default value state on the first call. It is done because computing default on each call is too expensive.
- Kotlin 1.5.10
- Build tools 0.10.0
- Relaxed type restriction on `MetaConverter`. Now nullables are available.
- **Huge API-breaking refactoring of Meta**. Meta now can have both value and children. There is only one kind of descriptor now.
- **API breaking** `String.toName()` is replaced by `Name.parse()`
- **API breaking** Configurable`config` changed to `meta`
### Removed
- `Config`
- Public PluginManager mutability
- Tables and tables-exposed moved to the separate project `tables.kt`
- BinaryMetaFormat. Use CBOR encoding instead
### Fixed
- Proper json array index treatment.
- Proper json index for single-value array.
## 0.4.0
### Added
- LogManager plugin
- dataforge-context API dependency on SLF4j
- Context `withEnv` and `fetch` methods to manipulate plugins without changing plugins after creation.
- Split `ItemDescriptor` into builder and read-only part
### Changed
- Kotlin-logging moved from common to JVM and JS. Replaced by console for native.
- Package changed to `space.kscience`
- Scheme made observable
- Global context is a variable (the singleton is hidden and will be deprecated in future)
- Kotlin 1.5
- Added blank builders for children context.
- Refactor loggers
### Deprecated
- Direct use of PluginManager
### Removed
- Common dependency on Kotlin-logging
- Kotlinx-io fork dependency. Replaced by Ktor-io.
### Fixed
- Scheme properties properly handle children property change.
## 0.3.0
### Added
- Yaml meta format based on yaml.kt
- `Path` builders
- Special ValueType for lists
- `copy` method to descriptors
- Multiplatform yaml meta
### Changed
- `ListValue` and `DoubleArrayValue` implement `Iterable`.
- Changed the logic of `Value::isList` to check for type instead of size
- `Meta{}` builder made inline
- Moved `Envelope` builder to a top level function. Companion invoke is deprecated.
- Context logging moved to the extension
- `number` and `string` methods on `Value` moved to extensions (breaking change)
- \[Major breaking change\] Schemes and configurables us `MutableItemProvider` instead of `Config`
- \[Major breaking change\] `MetaItem` renamed to `TypedMetaItem` and `MetaItem` is now an alias for `TypedMetaItem<*>`
- \[Major breaking change\] Moved `NodeItem` and `ValueItem` to a top level
- Plugins are removed from Context constructor and added lazily in ContextBuilder
- \[Major breaking change\] Full refactor of DataTree/DataSource
- \[Major Breaking change\] Replace KClass with KType in data. Remove direct access to constructors with types.
## 0.2.0
### Changed
- Context content resolution refactor
- Kotlin 1.4.10 (build tools 0.6.0)
- Empty query in Name is null instead of ""
- Provider provides an empty map instead of error by default
- Hidden delegates hierarchy in favor of stdlib properties
- Removed io depdendency from `dataforge-output`. Replaced Output by Appendable.
- Configurable is no longer MutableItemProvider. All functionality moved to Scheme.
### Deprecated
- Context activation API
- TextRenderer
### Removed
- Functional server prototype
- `dataforge-output` module
### Fixed
- Global context CoroutineScope resolution
- Library mode compliance

201
LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,38 @@
[![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![DOI](https://zenodo.org/badge/148831678.svg)](https://zenodo.org/badge/latestdoi/148831678)
![Gradle build](https://github.com/mipt-npm/dataforge-core/workflows/Gradle%20build/badge.svg)
### [dataforge-context](dataforge-context)
> Context and provider definitions
>
> **Maturity**: DEVELOPMENT
### [dataforge-data](dataforge-data)
>
> **Maturity**: EXPERIMENTAL
### [dataforge-io](dataforge-io)
> IO module
>
> **Maturity**: EXPERIMENTAL
### [dataforge-meta](dataforge-meta)
> Meta definition and basic operations on meta
>
> **Maturity**: DEVELOPMENT
### [dataforge-scripting](dataforge-scripting)
>
> **Maturity**: PROTOTYPE
### [dataforge-workspace](dataforge-workspace)
>
> **Maturity**: EXPERIMENTAL
### [dataforge-io/dataforge-io-yaml](dataforge-io/dataforge-io-yaml)
> YAML meta converters and Front Matter envelope format
>
> **Maturity**: PROTOTYPE

View File

@ -1,18 +1,39 @@
val dataforgeVersion by extra("0.1.2")
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import space.kscience.gradle.useApache2Licence
import space.kscience.gradle.useSPCTeam
plugins {
id("space.kscience.gradle.project")
}
allprojects {
repositories {
jcenter()
maven("https://kotlin.bintray.com/kotlinx")
}
group = "hep.dataforge"
version = dataforgeVersion
group = "space.kscience"
version = "0.7.0"
}
subprojects {
if (name.startsWith("dataforge")) {
apply(plugin = "npm-bintray")
apply(plugin = "npm-artifactory")
}
apply(plugin = "maven-publish")
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers"
}
}
}
readme {
readmeTemplate = file("docs/templates/README-TEMPLATE.md")
}
ksciencePublish {
pom("https://github.com/SciProgCentre/kmath") {
useApache2Licence()
useSPCTeam()
}
repository("spc","https://maven.sciprog.center/kscience")
sonatype()
}
apiValidation {
nonPublicMarkers.add("space.kscience.dataforge.misc.DFExperimental")
}

View File

@ -1,20 +0,0 @@
plugins {
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
jcenter()
}
val kotlinVersion = "1.3.31"
// Add plugins used in buildSrc as dependencies, also we should specify version only here
dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.9.5")
implementation("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4")
implementation("org.jetbrains.dokka:dokka-gradle-plugin:0.9.18")
implementation("com.moowork.gradle:gradle-node-plugin:1.3.1")
implementation("org.openjfx:javafx-plugin:0.0.7")
}

View File

@ -1,9 +0,0 @@
// Instead of defining runtime properties and use them dynamically
// define version in buildSrc and have autocompletion and compile-time check
// Also dependencies itself can be moved here
object Versions {
val ioVersion = "0.1.8"
val coroutinesVersion = "1.2.1"
val atomicfuVersion = "0.12.6"
val serializationVersion = "0.11.0"
}

View File

@ -1,59 +0,0 @@
import org.jetbrains.dokka.gradle.DokkaTask
plugins {
kotlin("multiplatform")
id("org.jetbrains.dokka")
`maven-publish`
}
kotlin {
val dokka by tasks.getting(DokkaTask::class) {
outputFormat = "html"
outputDirectory = "$buildDir/javadoc"
jdkVersion = 8
kotlinTasks {
// dokka fails to retrieve sources from MPP-tasks so we only define the jvm task
listOf(tasks.getByPath("compileKotlinJvm"))
}
sourceRoot {
// assuming only single source dir
path = sourceSets["commonMain"].kotlin.srcDirs.first().toString()
platforms = listOf("Common")
}
// although the JVM sources are now taken from the task,
// we still define the jvm source root to get the JVM marker in the generated html
sourceRoot {
// assuming only single source dir
path = sourceSets["jvmMain"].kotlin.srcDirs.first().toString()
platforms = listOf("JVM")
}
}
val javadocJar by tasks.registering(Jar::class) {
dependsOn(dokka)
archiveClassifier.set("javadoc")
from("$buildDir/javadoc")
}
publishing {
// publications.filterIsInstance<MavenPublication>().forEach { publication ->
// if (publication.name == "kotlinMultiplatform") {
// // for our root metadata publication, set artifactId with a package and project name
// publication.artifactId = project.name
// } else {
// // for targets, set artifactId with a package, project name and target name (e.g. iosX64)
// publication.artifactId = "${project.name}-${publication.name}"
// }
// }
targets.all {
val publication = publications.findByName(name) as MavenPublication
// Patch publications with fake javadoc
publication.artifact(javadocJar.get())
}
}
}

View File

@ -1,44 +0,0 @@
import com.moowork.gradle.node.npm.NpmTask
import com.moowork.gradle.node.task.NodeTask
import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
plugins {
id("com.moowork.node")
kotlin("multiplatform")
}
node {
nodeModulesDir = file("$buildDir/node_modules")
}
val compileKotlinJs by tasks.getting(Kotlin2JsCompile::class)
val compileTestKotlinJs by tasks.getting(Kotlin2JsCompile::class)
val populateNodeModules by tasks.registering(Copy::class) {
dependsOn(compileKotlinJs)
from(compileKotlinJs.destinationDir)
kotlin.js().compilations["test"].runtimeDependencyFiles.forEach {
if (it.exists() && !it.isDirectory) {
from(zipTree(it.absolutePath).matching { include("*.js") })
}
}
into("$buildDir/node_modules")
}
val installMocha by tasks.registering(NpmTask::class) {
setWorkingDir(buildDir)
setArgs(listOf("install", "mocha"))
}
val runMocha by tasks.registering(NodeTask::class) {
dependsOn(compileTestKotlinJs, populateNodeModules, installMocha)
setScript(file("$buildDir/node_modules/mocha/bin/mocha"))
setArgs(listOf(compileTestKotlinJs.outputFile))
}
tasks["jsTest"].dependsOn(runMocha)

View File

@ -1,38 +0,0 @@
import groovy.lang.GroovyObject
import org.jfrog.gradle.plugin.artifactory.dsl.PublisherConfig
import org.jfrog.gradle.plugin.artifactory.dsl.ResolverConfig
plugins {
id("com.jfrog.artifactory")
}
artifactory {
val artifactoryUser: String? by project
val artifactoryPassword: String? by project
val artifactoryContextUrl = "http://npm.mipt.ru:8081/artifactory"
setContextUrl(artifactoryContextUrl)//The base Artifactory URL if not overridden by the publisher/resolver
publish(delegateClosureOf<PublisherConfig> {
repository(delegateClosureOf<GroovyObject> {
setProperty("repoKey", "gradle-dev-local")
setProperty("username", artifactoryUser)
setProperty("password", artifactoryPassword)
})
defaults(delegateClosureOf<GroovyObject>{
invokeMethod("publications", arrayOf("jvm", "js", "kotlinMultiplatform", "metadata"))
//TODO: This property is not available for ArtifactoryTask
//setProperty("publishBuildInfo", false)
setProperty("publishArtifacts", true)
setProperty("publishPom", true)
setProperty("publishIvy", false)
})
})
resolve(delegateClosureOf<ResolverConfig> {
repository(delegateClosureOf<GroovyObject> {
setProperty("repoKey", "gradle-dev")
setProperty("username", artifactoryUser)
setProperty("password", artifactoryPassword)
})
})
}

View File

@ -1,97 +0,0 @@
@file:Suppress("UnstableApiUsage")
import com.jfrog.bintray.gradle.BintrayExtension.PackageConfig
import com.jfrog.bintray.gradle.BintrayExtension.VersionConfig
// Old bintray.gradle script converted to real Gradle plugin (precompiled script plugin)
// It now has own dependencies and support type safe accessors
// Syntax is pretty close to what we had in Groovy
// (excluding Property.set and bintray dynamic configs)
plugins {
id("com.jfrog.bintray")
`maven-publish`
}
val vcs = "https://github.com/mipt-npm/kmath"
// Configure publishing
publishing {
repositories {
maven("https://bintray.com/mipt-npm/scientifik")
}
// Process each publication we have in this project
publications.filterIsInstance<MavenPublication>().forEach { publication ->
// use type safe pom config GSL insterad of old dynamic
publication.pom {
name.set(project.name)
description.set(project.description)
url.set(vcs)
licenses {
license {
name.set("The Apache Software License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
distribution.set("repo")
}
}
developers {
developer {
id.set("MIPT-NPM")
name.set("MIPT nuclear physics methods laboratory")
organization.set("MIPT")
organizationUrl.set("http://npm.mipt.ru")
}
}
scm {
url.set(vcs)
}
}
}
}
bintray {
// delegates for runtime properties
val bintrayUser: String? by project
val bintrayApiKey: String? by project
user = bintrayUser ?: System.getenv("BINTRAY_USER")
key = bintrayApiKey ?: System.getenv("BINTRAY_API_KEY")
publish = true
override = true // for multi-platform Kotlin/Native publishing
// We have to use delegateClosureOf because bintray supports only dynamic groovy syntax
// this is a problem of this plugin
pkg(delegateClosureOf<PackageConfig> {
userOrg = "mipt-npm"
repo = "scientifik"
name = "scientifik.kmath"
issueTrackerUrl = "https://github.com/mipt-npm/kmath/issues"
setLicenses("Apache-2.0")
vcsUrl = vcs
version(delegateClosureOf<VersionConfig> {
name = project.version.toString()
vcsTag = project.version.toString()
released = java.util.Date().toString()
})
})
tasks {
bintrayUpload {
dependsOn(publishToMavenLocal)
doFirst {
setPublications(project.publishing.publications
.filterIsInstance<MavenPublication>()
.filter { !it.name.contains("-test") && it.name != "kotlinMultiplatform" }
.map {
println("""Uploading artifact "${it.groupId}:${it.artifactId}:${it.version}" from publication "${it.name}""")
it.name //https://github.com/bintray/gradle-bintray-plugin/issues/256
})
}
}
}
}

View File

@ -1,86 +0,0 @@
import org.gradle.kotlin.dsl.*
plugins {
kotlin("multiplatform")
`maven-publish`
}
kotlin {
jvm {
compilations.all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
js {
compilations.all {
kotlinOptions {
metaInfo = true
sourceMap = true
sourceMapEmbedSources = "always"
moduleKind = "commonjs"
}
}
compilations.named("main") {
kotlinOptions {
main = "call"
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
api(kotlin("stdlib"))
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val jvmMain by getting {
dependencies {
api(kotlin("stdlib-jdk8"))
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
}
}
val jsMain by getting {
dependencies {
api(kotlin("stdlib-js"))
}
}
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
}
targets.all {
sourceSets.all {
languageSettings.progressiveMode = true
languageSettings.enableLanguageFeature("InlineClasses")
}
}
apply(plugin = "dokka-publish")
// Apply JS test configuration
val runJsTests by ext(false)
if (runJsTests) {
apply(plugin = "js-test")
}
}

View File

@ -0,0 +1,23 @@
# Module dataforge-context
Context and provider definitions
## Usage
## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-context:0.7.0`.
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-context:0.7.0")
}
```

View File

@ -0,0 +1,327 @@
public abstract class space/kscience/dataforge/context/AbstractPlugin : space/kscience/dataforge/context/Plugin {
public fun <init> ()V
public fun <init> (Lspace/kscience/dataforge/meta/Meta;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun attach (Lspace/kscience/dataforge/context/Context;)V
public fun dependsOn ()Ljava/util/Map;
public fun detach ()V
public fun getContext ()Lspace/kscience/dataforge/context/Context;
public fun getMeta ()Lspace/kscience/dataforge/meta/Meta;
public fun isAttached ()Z
protected final fun require (Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/reflect/KClass;Lspace/kscience/dataforge/meta/Meta;)Lkotlin/properties/ReadOnlyProperty;
public static synthetic fun require$default (Lspace/kscience/dataforge/context/AbstractPlugin;Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/reflect/KClass;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty;
}
public final class space/kscience/dataforge/context/AbstractPluginKt {
public static final fun associateByName (Ljava/util/Collection;)Ljava/util/Map;
}
public final class space/kscience/dataforge/context/ClassLoaderPlugin : space/kscience/dataforge/context/AbstractPlugin {
public static final field Companion Lspace/kscience/dataforge/context/ClassLoaderPlugin$Companion;
public fun <init> (Ljava/lang/ClassLoader;)V
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
public final fun services (Lkotlin/reflect/KClass;)Lkotlin/sequences/Sequence;
}
public final class space/kscience/dataforge/context/ClassLoaderPlugin$Companion {
public final fun getDEFAULT ()Lspace/kscience/dataforge/context/ClassLoaderPlugin;
}
public final class space/kscience/dataforge/context/ClassLoaderPluginKt {
public static final fun getClassLoaderPlugin (Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/ClassLoaderPlugin;
}
public class space/kscience/dataforge/context/Context : kotlinx/coroutines/CoroutineScope, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/misc/Named, space/kscience/dataforge/provider/Provider {
public static final field Companion Lspace/kscience/dataforge/context/Context$Companion;
public static final field PROPERTY_TARGET Ljava/lang/String;
public final fun buildContext (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
public static synthetic fun buildContext$default (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context;
public fun close ()V
public fun content (Ljava/lang/String;)Ljava/util/Map;
public final fun content (Ljava/lang/String;Z)Ljava/util/Map;
public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext;
public fun getDefaultTarget ()Ljava/lang/String;
public final fun getName ()Lspace/kscience/dataforge/names/Name;
public final fun getParent ()Lspace/kscience/dataforge/context/Context;
public final fun getPlugins ()Lspace/kscience/dataforge/context/PluginManager;
public final fun getProperties ()Lspace/kscience/dataforge/meta/Laminate;
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
}
public final class space/kscience/dataforge/context/Context$Companion {
}
public abstract interface class space/kscience/dataforge/context/ContextAware {
public abstract fun getContext ()Lspace/kscience/dataforge/context/Context;
}
public final class space/kscience/dataforge/context/ContextBuilder {
public final fun build ()Lspace/kscience/dataforge/context/Context;
public final fun getName ()Lspace/kscience/dataforge/names/Name;
public final fun plugin (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun plugin (Lspace/kscience/dataforge/context/Plugin;)V
public final fun plugin (Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)V
public final fun plugin (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)V
public final fun plugin (Lspace/kscience/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Lspace/kscience/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static synthetic fun plugin$default (Lspace/kscience/dataforge/context/ContextBuilder;Lspace/kscience/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public final fun properties (Lkotlin/jvm/functions/Function1;)V
}
public final class space/kscience/dataforge/context/ContextBuilderKt {
}
public final class space/kscience/dataforge/context/DefaultLogManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/dataforge/context/LogManager {
public static final field Companion Lspace/kscience/dataforge/context/DefaultLogManager$Companion;
public fun <init> ()V
public fun getDefaultLogger ()Lspace/kscience/dataforge/context/Logger;
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
public fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger;
}
public final class space/kscience/dataforge/context/DefaultLogManager$Companion : space/kscience/dataforge/context/PluginFactory {
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/context/DefaultLogManager;
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
}
public abstract interface class space/kscience/dataforge/context/Factory {
public abstract fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
}
public final class space/kscience/dataforge/context/FactoryKt {
public static final fun invoke (Lspace/kscience/dataforge/context/Factory;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;)Ljava/lang/Object;
public static synthetic fun invoke$default (Lspace/kscience/dataforge/context/Factory;Lspace/kscience/dataforge/meta/Meta;Lspace/kscience/dataforge/context/Context;ILjava/lang/Object;)Ljava/lang/Object;
}
public final class space/kscience/dataforge/context/GlobalKt {
public static final fun Context (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Context;
public static synthetic fun Context$default (Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Context;
public static final fun getGlobal ()Lspace/kscience/dataforge/context/Context;
}
public abstract interface class space/kscience/dataforge/context/LogManager : space/kscience/dataforge/context/Logger, space/kscience/dataforge/context/Plugin {
public static final field Companion Lspace/kscience/dataforge/context/LogManager$Companion;
public static final field DEBUG Ljava/lang/String;
public static final field ERROR Ljava/lang/String;
public static final field INFO Ljava/lang/String;
public static final field TRACE Ljava/lang/String;
public static final field WARNING Ljava/lang/String;
public abstract fun getDefaultLogger ()Lspace/kscience/dataforge/context/Logger;
public fun log (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
public fun log (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
public abstract fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger;
}
public final class space/kscience/dataforge/context/LogManager$Companion {
public static final field DEBUG Ljava/lang/String;
public static final field ERROR Ljava/lang/String;
public static final field INFO Ljava/lang/String;
public static final field TRACE Ljava/lang/String;
public static final field WARNING Ljava/lang/String;
}
public final class space/kscience/dataforge/context/LogManagerKt {
public static final fun debug (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
public static final fun error (Lspace/kscience/dataforge/context/Logger;Ljava/lang/Throwable;Lkotlin/jvm/functions/Function0;)V
public static final fun error (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
public static final fun getLogger (Lspace/kscience/dataforge/context/Context;)Lspace/kscience/dataforge/context/LogManager;
public static final fun getLogger (Lspace/kscience/dataforge/context/ContextAware;)Lspace/kscience/dataforge/context/Logger;
public static final fun info (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
public static final fun trace (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
public static final fun warn (Lspace/kscience/dataforge/context/Logger;Lkotlin/jvm/functions/Function0;)V
}
public abstract interface class space/kscience/dataforge/context/Logger {
public abstract fun log (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
}
public abstract interface class space/kscience/dataforge/context/Plugin : space/kscience/dataforge/context/ContextAware, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/misc/Named, space/kscience/dataforge/provider/Provider {
public static final field Companion Lspace/kscience/dataforge/context/Plugin$Companion;
public static final field TARGET Ljava/lang/String;
public abstract fun attach (Lspace/kscience/dataforge/context/Context;)V
public abstract fun dependsOn ()Ljava/util/Map;
public abstract fun detach ()V
public abstract fun getMeta ()Lspace/kscience/dataforge/meta/Meta;
public fun getName ()Lspace/kscience/dataforge/names/Name;
public abstract fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
public abstract fun isAttached ()Z
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
}
public final class space/kscience/dataforge/context/Plugin$Companion {
public static final field TARGET Ljava/lang/String;
}
public final class space/kscience/dataforge/context/PluginBuilder {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun build ()Lspace/kscience/dataforge/context/PluginFactory;
public final fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
public final fun provides (Ljava/lang/String;Ljava/util/Map;)V
public final fun provides (Ljava/lang/String;[Lspace/kscience/dataforge/misc/Named;)V
public final fun requires (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;)V
public static synthetic fun requires$default (Lspace/kscience/dataforge/context/PluginBuilder;Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;ILjava/lang/Object;)V
}
public final class space/kscience/dataforge/context/PluginBuilderKt {
public static final fun PluginFactory (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/PluginFactory;
public static synthetic fun PluginFactory$default (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/PluginFactory;
}
public abstract interface class space/kscience/dataforge/context/PluginFactory : space/kscience/dataforge/context/Factory {
public static final field Companion Lspace/kscience/dataforge/context/PluginFactory$Companion;
public static final field TYPE Ljava/lang/String;
public abstract fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
}
public final class space/kscience/dataforge/context/PluginFactory$Companion {
public static final field TYPE Ljava/lang/String;
}
public final class space/kscience/dataforge/context/PluginManager : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker, space/kscience/dataforge/context/ContextAware {
public final fun find (ZLkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Plugin;
public static synthetic fun find$default (Lspace/kscience/dataforge/context/PluginManager;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Plugin;
public final fun get (Lspace/kscience/dataforge/context/PluginTag;Z)Lspace/kscience/dataforge/context/Plugin;
public static synthetic fun get$default (Lspace/kscience/dataforge/context/PluginManager;Lspace/kscience/dataforge/context/PluginTag;ZILjava/lang/Object;)Lspace/kscience/dataforge/context/Plugin;
public final fun getByType (Lkotlin/reflect/KClass;Lspace/kscience/dataforge/context/PluginTag;Z)Ljava/lang/Object;
public static synthetic fun getByType$default (Lspace/kscience/dataforge/context/PluginManager;Lkotlin/reflect/KClass;Lspace/kscience/dataforge/context/PluginTag;ZILjava/lang/Object;)Ljava/lang/Object;
public fun getContext ()Lspace/kscience/dataforge/context/Context;
public fun iterator ()Ljava/util/Iterator;
public final fun list (Z)Ljava/util/Collection;
}
public final class space/kscience/dataforge/context/PluginTag : space/kscience/dataforge/meta/MetaRepr {
public static final field Companion Lspace/kscience/dataforge/context/PluginTag$Companion;
public static final field DATAFORGE_GROUP Ljava/lang/String;
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lspace/kscience/dataforge/context/PluginTag;
public static synthetic fun copy$default (Lspace/kscience/dataforge/context/PluginTag;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lspace/kscience/dataforge/context/PluginTag;
public fun equals (Ljava/lang/Object;)Z
public final fun getGroup ()Ljava/lang/String;
public final fun getName ()Ljava/lang/String;
public final fun getVersion ()Ljava/lang/String;
public fun hashCode ()I
public final fun matches (Lspace/kscience/dataforge/context/PluginTag;)Z
public fun toMeta ()Lspace/kscience/dataforge/meta/Meta;
public fun toString ()Ljava/lang/String;
}
public final class space/kscience/dataforge/context/PluginTag$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lspace/kscience/dataforge/context/PluginTag$$serializer;
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/dataforge/context/PluginTag;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/dataforge/context/PluginTag;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}
public final class space/kscience/dataforge/context/PluginTag$Companion {
public final fun fromString (Ljava/lang/String;)Lspace/kscience/dataforge/context/PluginTag;
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class space/kscience/dataforge/context/ResolveKt {
public static final fun gather (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;Lkotlin/reflect/KClass;Z)Ljava/util/Map;
public static synthetic fun gather$default (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;Lkotlin/reflect/KClass;ZILjava/lang/Object;)Ljava/util/Map;
public static final fun getValues (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
public static final fun resolve (Lspace/kscience/dataforge/context/Context;Ljava/lang/String;Lspace/kscience/dataforge/names/Name;Lkotlin/reflect/KClass;)Ljava/lang/Object;
}
public final class space/kscience/dataforge/context/SlfLogManager : space/kscience/dataforge/context/AbstractPlugin, space/kscience/dataforge/context/LogManager {
public static final field Companion Lspace/kscience/dataforge/context/SlfLogManager$Companion;
public fun <init> ()V
public fun getDefaultLogger ()Lspace/kscience/dataforge/context/Logger;
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
public fun logger (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/context/Logger;
}
public final class space/kscience/dataforge/context/SlfLogManager$Companion : space/kscience/dataforge/context/PluginFactory {
public synthetic fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Ljava/lang/Object;
public fun build (Lspace/kscience/dataforge/context/Context;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/context/SlfLogManager;
public fun getTag ()Lspace/kscience/dataforge/context/PluginTag;
}
public final class space/kscience/dataforge/properties/PropertyKt {
}
public final class space/kscience/dataforge/properties/SchemePropertyKt {
}
public final class space/kscience/dataforge/provider/DfTypeKt {
}
public final class space/kscience/dataforge/provider/Path : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker {
public static final field Companion Lspace/kscience/dataforge/provider/Path$Companion;
public static final field PATH_SEGMENT_SEPARATOR Ljava/lang/String;
public static final synthetic fun box-impl (Ljava/util/List;)Lspace/kscience/dataforge/provider/Path;
public static fun constructor-impl (Ljava/util/List;)Ljava/util/List;
public fun equals (Ljava/lang/Object;)Z
public static fun equals-impl (Ljava/util/List;Ljava/lang/Object;)Z
public static final fun equals-impl0 (Ljava/util/List;Ljava/util/List;)Z
public final fun getTokens ()Ljava/util/List;
public fun hashCode ()I
public static fun hashCode-impl (Ljava/util/List;)I
public fun iterator ()Ljava/util/Iterator;
public static fun iterator-impl (Ljava/util/List;)Ljava/util/Iterator;
public fun toString ()Ljava/lang/String;
public static fun toString-impl (Ljava/util/List;)Ljava/lang/String;
public final synthetic fun unbox-impl ()Ljava/util/List;
}
public final class space/kscience/dataforge/provider/Path$Companion {
public final fun parse-X5wN5Vs (Ljava/lang/String;)Ljava/util/List;
}
public final class space/kscience/dataforge/provider/PathKt {
public static final fun Path ([Lkotlin/Pair;)Ljava/util/List;
public static final fun Path ([Lspace/kscience/dataforge/names/Name;)Ljava/util/List;
public static final fun asPath (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;)Ljava/util/List;
public static final fun asPath (Lspace/kscience/dataforge/provider/PathToken;)Ljava/util/List;
public static synthetic fun asPath$default (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;ILjava/lang/Object;)Ljava/util/List;
public static final fun getHead-LGjlSZY (Ljava/util/List;)Lspace/kscience/dataforge/provider/PathToken;
public static final fun getLength-LGjlSZY (Ljava/util/List;)I
public static final fun getTail-LGjlSZY (Ljava/util/List;)Ljava/util/List;
public static final fun plus-sn2Gq0g (Ljava/util/List;Ljava/util/List;)Ljava/util/List;
}
public final class space/kscience/dataforge/provider/PathToken {
public static final field Companion Lspace/kscience/dataforge/provider/PathToken$Companion;
public static final field TARGET_SEPARATOR Ljava/lang/String;
public fun <init> (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;)V
public synthetic fun <init> (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lspace/kscience/dataforge/names/Name;
public final fun component2 ()Ljava/lang/String;
public final fun copy (Lspace/kscience/dataforge/names/Name;Ljava/lang/String;)Lspace/kscience/dataforge/provider/PathToken;
public static synthetic fun copy$default (Lspace/kscience/dataforge/provider/PathToken;Lspace/kscience/dataforge/names/Name;Ljava/lang/String;ILjava/lang/Object;)Lspace/kscience/dataforge/provider/PathToken;
public fun equals (Ljava/lang/Object;)Z
public final fun getName ()Lspace/kscience/dataforge/names/Name;
public final fun getTarget ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class space/kscience/dataforge/provider/PathToken$Companion {
public final fun parse (Ljava/lang/String;Z)Lspace/kscience/dataforge/provider/PathToken;
public static synthetic fun parse$default (Lspace/kscience/dataforge/provider/PathToken$Companion;Ljava/lang/String;ZILjava/lang/Object;)Lspace/kscience/dataforge/provider/PathToken;
}
public abstract interface class space/kscience/dataforge/provider/Provider {
public fun content (Ljava/lang/String;)Ljava/util/Map;
public fun getDefaultChainTarget ()Ljava/lang/String;
public fun getDefaultTarget ()Ljava/lang/String;
}
public final class space/kscience/dataforge/provider/ProviderKt {
public static final fun provide-CSkoCSg (Lspace/kscience/dataforge/provider/Provider;Ljava/util/List;Ljava/lang/String;)Ljava/lang/Object;
public static synthetic fun provide-CSkoCSg$default (Lspace/kscience/dataforge/provider/Provider;Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/Object;
public static final fun top (Lspace/kscience/dataforge/provider/Provider;Ljava/lang/String;Lkotlin/reflect/KClass;)Ljava/util/Map;
}

View File

@ -1,36 +1,24 @@
plugins {
`npm-multiplatform`
id("space.kscience.gradle.mpp")
}
description = "Context and provider definitions"
val coroutinesVersion: String = Versions.coroutinesVersion
kotlin {
kscience {
jvm()
js()
sourceSets {
val commonMain by getting {
dependencies {
api(project(":dataforge-meta"))
api(kotlin("reflect"))
api("io.github.microutils:kotlin-logging-common:1.6.10")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion")
}
}
val jvmMain by getting {
dependencies {
api("io.github.microutils:kotlin-logging:1.6.10")
api("ch.qos.logback:logback-classic:1.2.3")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
}
}
val jsMain by getting {
dependencies {
api("io.github.microutils:kotlin-logging-js:1.6.10")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion")
}
}
native()
useCoroutines()
useSerialization()
dependencies {
api(project(":dataforge-meta"))
}
dependencies(jvmMain){
api(kotlin("reflect"))
api("org.slf4j:slf4j-api:1.7.30")
}
}
readme {
maturity = space.kscience.gradle.Maturity.DEVELOPMENT
}

View File

@ -1,24 +0,0 @@
package hep.dataforge.context
import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta
import hep.dataforge.names.Name
abstract class AbstractPlugin(override val meta: Meta = EmptyMeta) : Plugin {
private var _context: Context? = null
override val context: Context
get() = _context ?: error("Plugin $tag is not attached")
override fun attach(context: Context) {
this._context = context
}
override fun detach() {
this._context = null
}
override fun provideTop(target: String, name: Name): Any? = null
override fun listNames(target: String): Sequence<Name> = emptySequence()
}

View File

@ -1,183 +0,0 @@
package hep.dataforge.context
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.appendLeft
import hep.dataforge.names.toName
import hep.dataforge.provider.Provider
import hep.dataforge.provider.top
import hep.dataforge.values.Value
import kotlinx.coroutines.CoroutineScope
import mu.KLogger
import mu.KotlinLogging
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.jvm.JvmName
/**
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
* Context has [properties] - equivalent for system environment values, but grouped into a tree and inherited from parent context.
*
* The main function of the Context is to provide [PluginManager] which stores the loaded plugins and works as a dependency injection point.
* The normal behaviour of the [PluginManager] is to search for a plugin in parent context if it is not found in a current one. It is possible to have
* different plugins with the same interface in different contexts in the hierarchy. The usual behaviour is to use nearest one, but it could
* be overridden by plugin implementation.
*
* Since plugins could contain mutable state, context has two states: active and inactive. No changes are allowed to active context.
* @author Alexander Nozik
*/
open class Context(final override val name: String, val parent: Context? = Global) : Named, MetaRepr, Provider,
CoroutineScope {
private val config = Config()
/**
* Context properties. Working as substitute for environment variables
*/
val properties: Meta = if (parent == null) {
config
} else {
Laminate(config, parent.properties)
}
/**
* Context logger
*/
val logger: KLogger = KotlinLogging.logger(name)
/**
* A [PluginManager] for current context
*/
val plugins: PluginManager by lazy { PluginManager(this) }
private val activators = HashSet<Any>()
/**
* Defines if context is used in any kind of active computations. Active context properties and plugins could not be changed
*/
val isActive: Boolean = activators.isNotEmpty()
override val defaultTarget: String get() = Plugin.PLUGIN_TARGET
override fun provideTop(target: String, name: Name): Any? {
return when (target) {
Plugin.PLUGIN_TARGET -> plugins[PluginTag.fromString(name.toString())]
Value.TYPE -> properties[name]?.value
else -> null
}
}
override fun listNames(target: String): Sequence<Name> {
return when (target) {
Plugin.PLUGIN_TARGET -> plugins.asSequence().map { it.name.toName() }
Value.TYPE -> properties.values().map { it.first }
else -> emptySequence()
}
}
/**
* Mark context as active and used by [activator]
*/
fun activate(activator: Any) {
activators.add(activator)
}
/**
* Mark context unused by [activator]
*/
fun deactivate(activator: Any) {
activators.remove(activator)
}
/**
* Change the properties of the context. If active, throw an exception
*/
fun configure(action: Config.() -> Unit) {
if (isActive) error("Can't configure active context")
config.action()
}
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
/**
* Detach all plugins and terminate context
*/
open fun close() {
if (isActive) error("Can't close active context")
//detach all plugins
plugins.forEach { it.detach() }
}
override fun toMeta(): Meta = buildMeta {
"parent" to parent?.name
"properties" to properties.seal()
"plugins" to plugins.map { it.toMeta() }
}
}
/**
* A sequences of all objects provided by plugins with given target and type
*/
fun Context.content(target: String): Map<Name, Any> = content<Any>(target)
@JvmName("typedContent")
inline fun <reified T : Any> Context.content(target: String): Map<Name, T> =
plugins.flatMap { plugin ->
plugin.top<T>(target).entries.map { (it.key.appendLeft(plugin.name)) to it.value }
}.associate { it }
/**
* A global root context. Closing [Global] terminates the framework.
*/
object Global : Context("GLOBAL", null) {
/**
* Closing all contexts
*
* @throws Exception
*/
override fun close() {
logger.info { "Shutting down GLOBAL" }
for (ctx in contextRegistry.values) {
ctx.close()
}
super.close()
}
private val contextRegistry = HashMap<String, Context>()
/**
* Get previously builder context o builder a new one
*
* @param name
* @return
*/
fun getContext(name: String): Context {
return contextRegistry.getOrPut(name) { Context(name) }
}
}
/**
* The interface for something that encapsulated in context
*
* @author Alexander Nozik
* @version $Id: $Id
*/
interface ContextAware {
/**
* Get context for this object
*
* @return
*/
val context: Context
val logger: KLogger
get() = if (this is Named) {
KotlinLogging.logger(context.name + "." + (this as Named).name)
} else {
context.logger
}
}

View File

@ -1,36 +0,0 @@
package hep.dataforge.context
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.buildMeta
/**
* A convenience builder for context
*/
class ContextBuilder(var name: String = "@anonimous", val parent: Context = Global) {
private val plugins = ArrayList<Plugin>()
private var meta = MetaBuilder()
fun properties(action: MetaBuilder.() -> Unit) {
meta.action()
}
fun plugin(plugin: Plugin) {
plugins.add(plugin)
}
fun plugin(tag: PluginTag, action: MetaBuilder.() -> Unit) {
plugins.add(PluginRepository.fetch(tag, buildMeta(action)))
}
fun plugin(name: String, group: String = "", version: String = "", action: MetaBuilder.() -> Unit) {
plugin(PluginTag(name, group, version), action)
}
fun build(): Context {
return Context(name, parent).apply {
this@ContextBuilder.plugins.forEach {
plugins.load(it)
}
}
}
}

View File

@ -1,171 +0,0 @@
package hep.dataforge.context
import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.buildMeta
import kotlin.reflect.KClass
/**
* The manager for plugin system. Should monitor plugin dependencies and locks.
*
* @property context A context for this plugin manager
* @author Alexander Nozik
*/
class PluginManager(override val context: Context) : ContextAware, Iterable<Plugin> {
/**
* A set of loaded plugins
*/
private val plugins = HashSet<Plugin>()
/**
* A [PluginManager] of parent context if it is present
*/
private val parent: PluginManager? = context.parent?.plugins
fun sequence(recursive: Boolean): Sequence<Plugin> {
return if (recursive && parent != null) {
plugins.asSequence() + parent.sequence(true)
} else {
plugins.asSequence()
}
}
/**
* Get existing plugin or return null if not present. Only first matching plugin is returned.
* @param recursive search for parent [PluginManager] plugins
* @param predicate condition for the plugin
*/
fun get(recursive: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = sequence(recursive).find(predicate)
/**
* Find a loaded plugin via its tag
*
* @param tag
* @return
*/
operator fun get(tag: PluginTag, recursive: Boolean = true): Plugin? = get(recursive) { tag.matches(it.tag) }
/**
* Find a loaded plugin via its class
*
* @param tag
* @param type
* @param <T>
* @return
*/
@Suppress("UNCHECKED_CAST")
operator fun <T : Plugin> get(type: KClass<T>, recursive: Boolean = true): T? =
get(recursive) { type.isInstance(it) } as T?
inline fun <reified T : Plugin> get(recursive: Boolean = true): T? = get(T::class, recursive)
/**
* Load given plugin into this manager and return loaded instance.
* Throw error if plugin of the same class already exists in manager
*
* @param plugin
* @return
*/
fun <T : Plugin> load(plugin: T): T {
if (context.isActive) error("Can't load plugin into active context")
if (get(plugin::class, false) != null) {
throw RuntimeException("Plugin of type ${plugin::class} already exists in ${context.name}")
} else {
loadDependencies(plugin)
logger.info { "Loading plugin ${plugin.name} into ${context.name}" }
plugin.attach(context)
plugins.add(plugin)
return plugin
}
}
private fun loadDependencies(plugin: Plugin) {
for (tag in plugin.dependsOn()) {
load(tag)
}
}
/**
* Remove a plugin from [PluginManager]
*/
fun remove(plugin: Plugin) {
if (context.isActive) error("Can't remove plugin from active context")
if (plugins.contains(plugin)) {
logger.info { "Removing plugin ${plugin.name} from ${context.name}" }
plugin.detach()
plugins.remove(plugin)
}
}
/**
* Get plugin instance via plugin resolver and load it.
*
* @param tag
* @return
*/
fun load(tag: PluginTag, meta: Meta = EmptyMeta): Plugin {
val loaded = get(tag, false)
return when {
loaded == null -> load(PluginRepository.fetch(tag,meta))
loaded.meta == meta -> loaded // if meta is the same, return existing plugin
else -> throw RuntimeException("Can't load plugin with tag $tag. Plugin with this tag and different configuration already exists in context.")
}
}
fun load(factory: PluginFactory<*>, meta: Meta = EmptyMeta): Plugin{
val loaded = get(factory.tag, false)
return when {
loaded == null -> load(factory(meta))
loaded.meta == meta -> loaded // if meta is the same, return existing plugin
else -> throw RuntimeException("Can't load plugin with tag ${factory.tag}. Plugin with this tag and different configuration already exists in context.")
}
}
/**
* Load plugin by its class and meta. Ignore if plugin with this meta is already loaded.
* Throw an exception if there exists plugin with the same type, but different meta
*/
fun <T : Plugin> load(type: KClass<T>, meta: Meta = EmptyMeta): T {
val loaded = get(type, false)
return when {
loaded == null -> {
val plugin = PluginRepository.list().first { it.type == type }.invoke(meta)
if (type.isInstance(plugin)) {
@Suppress("UNCHECKED_CAST")
load(plugin as T)
} else {
error("Corrupt type information in plugin repository")
}
}
loaded.meta == meta -> loaded // if meta is the same, return existing plugin
else -> throw RuntimeException("Can't load plugin with type $type. Plugin with this type and different configuration already exists in context.")
}
}
inline fun <reified T : Plugin> load(noinline metaBuilder: MetaBuilder.() -> Unit = {}): T {
return load(T::class, buildMeta(metaBuilder))
}
fun load(name: String, meta: Meta = EmptyMeta): Plugin {
return load(PluginTag.fromString(name), meta)
}
override fun iterator(): Iterator<Plugin> = plugins.iterator()
/**
* Get a plugin if it exists or load it with given meta if it is not.
*/
inline fun <reified T : Plugin> getOrLoad(noinline metaBuilder: MetaBuilder.() -> Unit = {}): T {
return get(true) ?: load(metaBuilder)
}
}

View File

@ -1,49 +0,0 @@
package hep.dataforge.context
import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta
import kotlin.reflect.KClass
interface PluginFactory<T : Plugin> {
val tag: PluginTag
val type: KClass<out T>
operator fun invoke(meta: Meta = EmptyMeta): T
}
expect object PluginRepository {
fun register(factory: PluginFactory<*>)
/**
* List plugins available in the repository
*/
fun list(): Sequence<PluginFactory<*>>
}
/**
* Fetch specific plugin and instantiate it with given meta
*/
fun PluginRepository.fetch(tag: PluginTag, meta: Meta = EmptyMeta): Plugin =
list().find { it.tag.matches(tag) }?.invoke(meta) ?: error("Plugin with tag $tag not found in the repository")
fun <T : Plugin> PluginRepository.register(
tag: PluginTag,
type: KClass<out T>,
constructor: (Meta) -> T
): PluginFactory<T> {
val factory = object : PluginFactory<T> {
override val tag: PluginTag = tag
override val type: KClass<out T> = type
override fun invoke(meta: Meta): T = constructor(meta)
}
register(factory)
return factory
}
inline fun <reified T : Plugin> PluginRepository.register(tag: PluginTag, noinline constructor: (Meta) -> T) =
register(tag, T::class, constructor)
fun PluginRepository.register(plugin: Plugin) = register(plugin.tag, plugin::class) { plugin }

View File

@ -1,75 +0,0 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hep.dataforge.provider
import hep.dataforge.names.Name
import hep.dataforge.names.toName
/**
*
*
* Path interface.
*
* @author Alexander Nozik
* @version $Id: $Id
*/
inline class Path(val tokens: List<PathToken>) : Iterable<PathToken> {
val head: PathToken? get() = tokens.firstOrNull()
val length: Int get() = tokens.size
/**
* Returns non-empty optional containing the chain without first segment in case of chain path.
*
* @return
*/
val tail: Path? get() = if (tokens.isEmpty()) null else Path(tokens.drop(1))
override fun iterator(): Iterator<PathToken> = tokens.iterator()
companion object {
const val PATH_SEGMENT_SEPARATOR = "/"
fun parse(path: String): Path {
val head = path.substringBefore(PATH_SEGMENT_SEPARATOR)
val tail = path.substringAfter(PATH_SEGMENT_SEPARATOR)
return PathToken.parse(head).toPath() + parse(tail)
}
}
}
operator fun Path.plus(path: Path) = Path(this.tokens + path.tokens)
data class PathToken(val name: Name, val target: String? = null) {
override fun toString(): String = if (target == null) {
name.toString()
} else {
"$target$TARGET_SEPARATOR$name"
}
companion object {
const val TARGET_SEPARATOR = "::"
fun parse(token: String): PathToken {
val target = token.substringBefore(TARGET_SEPARATOR, "")
val name = token.substringAfter(TARGET_SEPARATOR).toName()
if (target.contains("[")) TODO("target separators in queries are not supported")
return PathToken(name, target)
}
}
}
fun PathToken.toPath() = Path(listOf(this))

View File

@ -1,100 +0,0 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hep.dataforge.provider
import hep.dataforge.names.Name
import hep.dataforge.names.toName
import kotlin.jvm.JvmName
/**
* A marker utility interface for providers.
*
* @author Alexander Nozik
*/
interface Provider {
/**
* Default target for this provider
*
* @return
*/
val defaultTarget: String get() = ""
/**
* Default target for next chain segment
*
* @return
*/
val defaultChainTarget: String get() = ""
/**
* Provide a top level element for this [Provider] or return null if element is not present
*/
fun provideTop(target: String, name: Name): Any?
/**
* [Sequence] of available names with given target. Only top level names are listed, no chain path.
*
* @param target
* @return
*/
fun listNames(target: String): Sequence<Name>
}
fun Provider.provide(path: Path, targetOverride: String? = null): Any? {
if (path.length == 0) throw IllegalArgumentException("Can't provide by empty path")
val first = path.first()
val top = provideTop(targetOverride ?: first.target ?: defaultTarget, first.name)
return when (path.length) {
1 -> top
else -> {
when (top) {
null -> null
is Provider -> top.provide(path.tail!!, targetOverride = defaultChainTarget)
else -> throw IllegalStateException("Chain path not supported: child is not a provider")
}
}
}
}
/**
* Type checked provide
*/
inline fun <reified T : Any> Provider.provide(path: String): T? {
return provide(Path.parse(path)) as? T
}
inline fun <reified T : Any> Provider.provide(target: String, name: Name): T? {
return provide(PathToken(name, target).toPath()) as? T
}
inline fun <reified T : Any> Provider.provide(target: String, name: String): T? =
provide(target, name.toName())
/**
* A top level content with names
*/
fun Provider.top(target: String): Map<Name, Any> = top<Any>(target)
@JvmName("typedTop")
inline fun <reified T : Any> Provider.top(target: String): Map<Name, T> {
return listNames(target).associate {
it to (provideTop(target, it) as? T ?: error("The element $it is declared but not provided"))
}
}

View File

@ -0,0 +1,57 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.names.Name
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
public abstract class AbstractPlugin(override val meta: Meta = Meta.EMPTY) : Plugin {
private var _context: Context? = null
private val dependencies = HashMap<PluginFactory<*>, Meta>()
override val isAttached: Boolean get() = _context != null
override val context: Context
get() = _context ?: error("Plugin $tag is not attached")
override fun attach(context: Context) {
this._context = context
}
override fun detach() {
this._context = null
}
override fun dependsOn(): Map<PluginFactory<*>, Meta> = dependencies
protected fun <P : Plugin> require(
factory: PluginFactory<P>,
type: KClass<P>,
meta: Meta = Meta.EMPTY,
): ReadOnlyProperty<AbstractPlugin, P> {
dependencies[factory] = meta
return PluginDependencyDelegate(factory, type)
}
/**
* Register plugin dependency and return a delegate which provides lazily initialized reference to dependent plugin
*/
protected inline fun <reified P : Plugin> require(
factory: PluginFactory<P>,
meta: Meta = Meta.EMPTY,
): ReadOnlyProperty<AbstractPlugin, P> = require(factory, P::class, meta)
}
public fun <T : Named> Collection<T>.associateByName(): Map<Name, T> = associate { it.name to it }
private class PluginDependencyDelegate<P : Plugin>(val factory: PluginFactory<P>, val type: KClass<P>) :
ReadOnlyProperty<AbstractPlugin, P> {
@OptIn(DFInternal::class)
override fun getValue(thisRef: AbstractPlugin, property: KProperty<*>): P {
if (!thisRef.isAttached) error("Plugin dependency must not be called eagerly during initialization.")
return thisRef.context.plugins.getByType(type, factory.tag) ?: error("Plugin ${factory.tag} not found")
}
}

View File

@ -0,0 +1,119 @@
package space.kscience.dataforge.context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.misc.ThreadSafe
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.provider.Provider
import kotlin.coroutines.CoroutineContext
/**
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
* Context has [properties] - equivalent for system environment values, but grouped into a tree and inherited from parent context.
*
* The main function of the Context is to provide [PluginManager] which stores the loaded plugins and works as a dependency injection point.
* The normal behaviour of the [PluginManager] is to search for a plugin in parent context if it is not found in a current one. It is possible to have
* different plugins with the same interface in different contexts in the hierarchy. The usual behaviour is to use nearest one, but it could
* be overridden by plugin implementation.
*
*/
public open class Context internal constructor(
final override val name: Name,
public val parent: Context?,
plugins: Set<Plugin>, // set of unattached plugins
meta: Meta,
) : Named, MetaRepr, Provider, CoroutineScope {
/**
* Context properties. Working as substitute for environment variables
*/
public val properties: Laminate = if (parent == null) {
Laminate(meta)
} else {
Laminate(meta, parent.properties)
}
/**
* A [PluginManager] for current context
*/
public val plugins: PluginManager by lazy { PluginManager(this, plugins) }
override val defaultTarget: String get() = Plugin.TARGET
public fun content(target: String, inherit: Boolean): Map<Name, Any> {
return if (inherit) {
when (target) {
PROPERTY_TARGET -> properties.nodeSequence().toMap()
Plugin.TARGET -> plugins.list(true).associateBy { it.name }
else -> emptyMap()
}
} else {
when (target) {
PROPERTY_TARGET -> properties.layers.firstOrNull()?.nodeSequence()?.toMap() ?: emptyMap()
Plugin.TARGET -> plugins.list(false).associateBy { it.name }
else -> emptyMap()
}
}
}
override fun content(target: String): Map<Name, Any> = content(target, true)
override val coroutineContext: CoroutineContext by lazy {
(parent ?: Global).coroutineContext.let { parenContext ->
parenContext + SupervisorJob(parenContext[Job])
}
}
private val childrenContexts = HashMap<Name, Context>()
/**
* Get and validate existing context or build and register a new child context.
* @param name the relative (tail) name of the new context. If null, uses context hash code as a marker.
*/
@OptIn(DFExperimental::class)
@ThreadSafe
public fun buildContext(name: Name? = null, block: ContextBuilder.() -> Unit = {}): Context {
val existing = name?.let { childrenContexts[name] }
return existing?.modify(block) ?: ContextBuilder(this, name).apply(block).build().also {
childrenContexts[it.name] = it
}
}
/**
* Detach all plugins, and close child contexts
*/
public open fun close() {
//recursively closed child context
childrenContexts.forEach { it.value.close() }
//detach all plugins
plugins.forEach { it.detach() }
}
override fun toMeta(): Meta = Meta {
"parent" to parent?.name
properties.layers.firstOrNull()?.let { set("properties", it) }
"plugins" putIndexed plugins.map { it.toMeta() }
}
public companion object {
public const val PROPERTY_TARGET: String = "context.property"
}
}
/**
* The interface for something that encapsulated in context
*
*/
public interface ContextAware {
/**
* Get context for this object
*
* @return
*/
public val context: Context
}

View File

@ -0,0 +1,111 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.meta.seal
import space.kscience.dataforge.meta.toMutableMeta
import space.kscience.dataforge.misc.DFBuilder
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.NameToken
import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.plus
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set
/**
* A convenience builder for context
*/
@DFBuilder
public class ContextBuilder internal constructor(
private val parent: Context,
public val name: Name? = null,
meta: Meta = Meta.EMPTY,
) {
internal val factories = HashMap<PluginFactory<*>, Meta>()
internal var meta = meta.toMutableMeta()
public fun properties(action: MutableMeta.() -> Unit) {
meta.action()
}
@OptIn(DFExperimental::class)
private fun findPluginFactory(tag: PluginTag): PluginFactory<*> =
parent.gatherInSequence<PluginFactory<*>>(PluginFactory.TYPE).values
.find { it.tag.matches(tag) } ?: error("Can't resolve plugin factory for $tag")
public fun plugin(tag: PluginTag, mutableMeta: MutableMeta.() -> Unit = {}) {
val factory = findPluginFactory(tag)
factories[factory] = Meta(mutableMeta)
}
public fun plugin(factory: PluginFactory<*>, meta: Meta) {
factories[factory] = meta
}
public fun plugin(factory: PluginFactory<*>, mutableMeta: MutableMeta.() -> Unit = {}) {
factories[factory] = Meta(mutableMeta)
}
public fun plugin(name: String, group: String = "", version: String = "", action: MutableMeta.() -> Unit = {}) {
plugin(PluginTag(name, group, version), action)
}
/**
* Add de-facto existing plugin as a dependency
*/
public fun plugin(plugin: Plugin) {
plugin(DeFactoPluginFactory(plugin))
}
public fun build(): Context {
val contextName = name ?: NameToken("@auto",hashCode().toUInt().toString(16)).asName()
val plugins = HashMap<PluginTag, Plugin>()
fun addPlugin(factory: PluginFactory<*>, meta: Meta) {
val existing = plugins[factory.tag]
// Add if does not exist
if (existing == null) {
//TODO bypass if parent already has plugin with given meta?
val plugin = factory.build(parent, meta)
for ((depFactory, deoMeta) in plugin.dependsOn()) {
addPlugin(depFactory, deoMeta)
}
parent.logger.info { "Loading plugin ${plugin.name} into $contextName" }
plugins[plugin.tag] = plugin
} else if (existing.meta != meta) {
error("Plugin with tag ${factory.tag} and meta $meta already exists in $contextName")
}
//bypass if exists with the same meta
}
factories.forEach { (factory, meta) ->
addPlugin(factory, meta)
}
return Context(contextName, parent, plugins.values.toSet(), meta.seal())
}
}
/**
* Check if current context contains all plugins required by the builder and return it does or forks to a new context
* if it does not.
*/
@DFExperimental
public fun Context.modify(block: ContextBuilder.() -> Unit): Context {
fun Context.contains(factory: PluginFactory<*>, meta: Meta): Boolean {
val loaded = plugins[factory.tag] ?: return false
return loaded.meta == meta
}
val builder = ContextBuilder(this, name + "mod", properties).apply(block)
val requiresFork = builder.factories.any { (factory, meta) ->
!contains(factory, meta)
} || ((properties as Meta) == builder.meta)
return if (requiresFork) builder.build() else this
}

View File

@ -0,0 +1,12 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
public fun interface Factory<out T> {
public fun build(context: Context, meta: Meta): T
}
public operator fun <T> Factory<T>.invoke(
meta: Meta = Meta.EMPTY,
context: Context = Global,
): T = build(context, meta)

View File

@ -0,0 +1,24 @@
package space.kscience.dataforge.context
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.Job
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.parseAsName
import kotlin.coroutines.CoroutineContext
import kotlin.native.concurrent.ThreadLocal
internal expect fun getGlobalLoggerFactory(): PluginFactory<out LogManager>
/**
* A global root context. Closing [Global] terminates the framework.
*/
@ThreadLocal
private object GlobalContext : Context("GLOBAL".asName(), null, emptySet(), Meta.EMPTY) {
override val coroutineContext: CoroutineContext = Job() + CoroutineName("GlobalContext")
}
public val Global: Context get() = GlobalContext
public fun Context(name: String? = null, block: ContextBuilder.() -> Unit = {}): Context =
Global.buildContext(name?.parseAsName(), block)

View File

@ -0,0 +1,89 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.plus
public fun interface Logger {
public fun log(tag: String, body: () -> String)
}
public interface LogManager : Plugin, Logger {
public fun logger(name: Name): Logger
public val defaultLogger: Logger
override fun log(tag: String, body: () -> String): Unit = defaultLogger.log(tag, body)
public fun log(name: Name, tag: String, body: () -> String): Unit = logger(name).log(tag, body)
public companion object {
public const val TRACE: String = "TRACE"
public const val INFO: String = "INFO"
public const val DEBUG: String = "DEBUG"
public const val WARNING: String = "WARNING"
public const val ERROR: String = "ERROR"
}
}
public fun Logger.trace(body: () -> String): Unit = log(LogManager.TRACE, body)
public fun Logger.info(body: () -> String): Unit = log(LogManager.INFO, body)
public fun Logger.debug(body: () -> String): Unit = log(LogManager.DEBUG, body)
public fun Logger.warn(body: () -> String): Unit = log(LogManager.WARNING, body)
public fun Logger.error(body: () -> String): Unit = log(LogManager.ERROR, body)
internal val (() -> String).safe: String
get() = try {
invoke()
} catch (t: Throwable) {
"Error while evaluating log string: ${t.message}"
}
public fun Logger.error(throwable: Throwable?, body: () -> String): Unit = log(LogManager.ERROR) {
buildString {
appendLine(body())
throwable?.let { appendLine(throwable.stackTraceToString()) }
}
}
public class DefaultLogManager : AbstractPlugin(), LogManager {
override fun logger(name: Name): Logger = Logger { tag, body ->
val message: String = body.safe
println("$tag $name: [${context.name}] $message")
}
override val defaultLogger: Logger = logger(Name.EMPTY)
override val tag: PluginTag get() = Companion.tag
public companion object : PluginFactory<DefaultLogManager> {
override fun build(context: Context, meta: Meta): DefaultLogManager = DefaultLogManager()
override val tag: PluginTag = PluginTag(group = PluginTag.DATAFORGE_GROUP, name = "log.default")
}
}
/**
* Context log manager inherited from parent
*/
public val Context.logger: LogManager
get() = plugins.find(inherit = true) { it is LogManager } as? LogManager
?: getGlobalLoggerFactory().build(context = Global, meta = Meta.EMPTY).apply { attach(Global) }
/**
* The named proxy logger for a context member
*/
public val ContextAware.logger: Logger
get() = if (this is Named) {
Logger { tag, body ->
context.logger.log(this@logger.name + name, tag, body)
}
} else {
context.logger
}

View File

@ -1,78 +1,68 @@
package hep.dataforge.context
package space.kscience.dataforge.context
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaRepr
import hep.dataforge.meta.buildMeta
import hep.dataforge.provider.Provider
import space.kscience.dataforge.context.Plugin.Companion.TARGET
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MetaRepr
import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.parseAsName
import space.kscience.dataforge.provider.Provider
/**
* The interface to define a Context plugin. A plugin stores all runtime features of a context.
* The plugin is by default configurable and a Provider (both features could be ignored).
* The plugin must in most cases have an empty constructor in order to be able to load it from library.
*
*
* The plugin lifecycle is the following:
*
*
* create - configure - attach - detach - destroy
*
*
* Configuration of attached plugin is possible for a context which is not in a runtime mode, but it is not recommended.
*
* @author Alexander Nozik
*/
interface Plugin : Named, ContextAware, Provider, MetaRepr {
@DfId(TARGET)
public interface Plugin : Named, ContextAware, Provider, MetaRepr {
/**
* Get tag for this plugin
*
* @return
*/
val tag: PluginTag
public val tag: PluginTag
val meta: Meta
public val meta: Meta
/**
* The name of this plugin ignoring version and group
*
* @return
*/
override val name: String get() = tag.name
override val name: Name get() = tag.name.parseAsName()
/**
* Plugin dependencies which are required to attach this plugin. Plugin
* dependencies must be initialized and enabled in the Context before this
* plugin is enabled.
*
* @return
*/
fun dependsOn(): List<PluginFactory<*>> = emptyList()
public fun dependsOn(): Map<PluginFactory<*>, Meta>
/**
* Start this plugin and attach registration info to the context. This method
* should be called only via PluginManager to avoid dependency issues.
*
* @param context
*/
fun attach(context: Context)
public fun attach(context: Context)
/**
* Stop this plugin and remove registration info from context and other
* plugins. This method should be called only via PluginManager to avoid
* dependency issues.
*/
fun detach()
public fun detach()
override fun toMeta(): Meta = buildMeta {
"context" to context.name
public val isAttached: Boolean
override fun toMeta(): Meta = Meta {
"context" put context.name.toString()
"type" to this::class.simpleName
"tag" to tag
"meta" to meta
"tag" put tag
"meta" put meta
}
companion object {
const val PLUGIN_TARGET = "plugin"
public companion object {
public const val TARGET: String = "plugin"
}
}

View File

@ -0,0 +1,57 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.names.Name
/**
* A convenience factory to build simple plugins
*/
public class PluginBuilder(
name: String,
group: String = "",
version: String = "",
) {
public val tag: PluginTag = PluginTag(name, group, version)
private val content = HashMap<String, MutableMap<Name, Any>>()
private val dependencies = HashMap<PluginFactory<*>, Meta>()
public fun requires(
factory: PluginFactory<*>,
meta: Meta = Meta.EMPTY,
) {
dependencies[factory] = meta
}
public fun provides(target: String, items: Map<Name, Any>) {
content.getOrPut(target) { HashMap() }.putAll(items)
}
public fun provides(target: String, vararg items: Named) {
provides(target, items.associateBy { it.name })
}
public fun build(): PluginFactory<*> {
return object : PluginFactory<Plugin> {
override val tag: PluginTag get() = this@PluginBuilder.tag
override fun build(context: Context, meta: Meta): Plugin = object : AbstractPlugin() {
override val tag: PluginTag get() = this@PluginBuilder.tag
override fun content(target: String): Map<Name, Any> = this@PluginBuilder.content[target] ?: emptyMap()
override fun dependsOn(): Map<PluginFactory<*>, Meta> = this@PluginBuilder.dependencies
}
}
}
}
public fun PluginFactory(
name: String,
group: String = "",
version: String = "",
block: PluginBuilder.() -> Unit,
): PluginFactory<*> = PluginBuilder(name, group, version).apply(block).build()

View File

@ -0,0 +1,21 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DfId
@DfId(PluginFactory.TYPE)
public interface PluginFactory<T : Plugin> : Factory<T> {
public val tag: PluginTag
public companion object {
public const val TYPE: String = "pluginFactory"
}
}
/**
* Plugin factory created for the specific actual plugin
*/
internal class DeFactoPluginFactory<T : Plugin>(val plugin: T) : PluginFactory<T> {
override fun build(context: Context, meta: Meta): T = plugin
override val tag: PluginTag get() = plugin.tag
}

View File

@ -0,0 +1,100 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.names.plus
import kotlin.reflect.KClass
import kotlin.reflect.cast
/**
* The manager for plugin system. Should monitor plugin dependencies and locks.
*
* @property context A context for this plugin manager
* @author Alexander Nozik
*/
public class PluginManager internal constructor(
override val context: Context,
private val plugins: Set<Plugin>,
) : ContextAware, Iterable<Plugin> {
init {
plugins.forEach { it.attach(context) }
}
/**
* A [PluginManager] of parent context if it is present
*/
private val parent: PluginManager? = context.parent?.plugins
/**
* List plugins stored in this [PluginManager]. If [inherit] is true, include parent plugins as well
*/
public fun list(inherit: Boolean): Collection<Plugin> {
return if (inherit && parent != null) {
plugins + parent.list(true)
} else {
plugins
}
}
/**
* Get existing plugin or return null if not present. Only first matching plugin is returned.
* @param inherit search for parent [PluginManager] plugins
* @param predicate condition for the plugin
*/
public fun find(inherit: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? =
list(inherit).find(predicate)
/**
* Find a loaded plugin via its tag
*
* @param tag
* @return
*/
public operator fun get(tag: PluginTag, inherit: Boolean = true): Plugin? =
find(inherit) { tag.matches(it.tag) }
/**
* Find a loaded plugin via its class. This method does not check if the result is unique and just returns first
* plugin matching the class condition.
* For safe search provide a tag since tags are checked on load and plugins with the same tag are not allowed
* in the same context.
*
* @param tag
* @param type
* @param <T>
* @return
*/
@DFInternal
public fun <T : Any> getByType(type: KClass<T>, tag: PluginTag? = null, inherit: Boolean = true): T? =
find(inherit) { type.isInstance(it) && (tag == null || tag.matches(it.tag)) }?.let { type.cast(it) }
@OptIn(DFInternal::class)
public inline operator fun <reified T : Any> get(tag: PluginTag? = null, recursive: Boolean = true): T? =
getByType(T::class, tag, recursive)
@OptIn(DFInternal::class)
public inline operator fun <reified T : Plugin> get(factory: PluginFactory<T>, recursive: Boolean = true): T? =
getByType(T::class, factory.tag, recursive)
override fun iterator(): Iterator<Plugin> = plugins.iterator()
}
/**
* Fetch a plugin with given meta from the context. If the plugin (with given meta) is already registered, it is returned.
* Otherwise, new child context with the plugin is created. In the later case the context could be retrieved from the plugin.
*/
public inline fun <reified T : Plugin> Context.request(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T {
val existing = plugins[factory]
return if (existing != null && existing.meta == meta) existing
else {
buildContext(name = this@request.name + factory.tag.name) {
plugin(factory, meta)
}.plugins[factory]!!
}
}
@Deprecated("Replace with request", ReplaceWith("request(factory, meta)"))
public inline fun <reified T : Plugin> Context.fetch(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T =
request(factory, meta)

View File

@ -1,8 +1,8 @@
package hep.dataforge.context
package space.kscience.dataforge.context
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaRepr
import hep.dataforge.meta.buildMeta
import kotlinx.serialization.Serializable
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MetaRepr
/**
* The tag which contains information about name, group and version of some
@ -10,7 +10,8 @@ import hep.dataforge.meta.buildMeta
*
* @author Alexander Nozik
*/
data class PluginTag(
@Serializable
public data class PluginTag(
val name: String,
val group: String = "",
val version: String = ""
@ -22,7 +23,7 @@ data class PluginTag(
* @param otherTag
* @return
*/
fun matches(otherTag: PluginTag): Boolean {
public fun matches(otherTag: PluginTag): Boolean {
return matchesName(otherTag) && matchesGroup(otherTag)
}
@ -36,15 +37,15 @@ data class PluginTag(
override fun toString(): String = listOf(group, name, version).joinToString(separator = ":")
override fun toMeta(): Meta = buildMeta {
"name" to name
"group" to group
"version" to version
override fun toMeta(): Meta = Meta {
"name" put name
"group" put group
"version" put version
}
companion object {
public companion object {
const val DATAFORGE_GROUP = "hep.dataforge"
public const val DATAFORGE_GROUP: String = "dataforge"
/**
* Build new PluginTag from standard string representation
@ -52,7 +53,7 @@ data class PluginTag(
* @param tag
* @return
*/
fun fromString(tag: String): PluginTag {
public fun fromString(tag: String): PluginTag {
val sepIndex = tag.indexOf(":")
return if (sepIndex >= 0) {
PluginTag(group = tag.substring(0, sepIndex), name = tag.substring(sepIndex + 1))

View File

@ -0,0 +1,97 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.plus
import space.kscience.dataforge.provider.Provider
import space.kscience.dataforge.provider.top
import kotlin.reflect.KClass
import kotlin.reflect.cast
/**
* Resolve a specific element in top level elements of the provider and attempt to cast it to the given type
*/
private fun <T : Any> Provider.provide(target: String, name: Name, type: KClass<out T>): T? {
return content(target)[name]?.let { type.cast(it) }
}
/**
* Resolve a top level object with given [target] and [name] in a [Context] own scope or its plugins.
*/
public fun <T : Any> Context.resolve(target: String, name: Name, type: KClass<out T>): T? {
//Try searching for plugin an context property
provide(target, name, type)?.let { return it }
val pluginContent = plugins.mapNotNull { it.provide(target, name, type) }
return if (pluginContent.isEmpty()) {
parent?.resolve<T>(target, name, type)
} else {
pluginContent.single() // throws error in case of name/type conflicts
}
}
/**
* Resolve a top level object with given [target] and [name] in a [Context] own scope or its plugins.
*/
public inline fun <reified T : Any> Context.resolve(target: String, name: Name): T? =
resolve(target, name, T::class)
/**
* Gather a map of all top-level objects with given [target] from context plugins.
* Content from plugins is prefixed by plugin name so name conflicts are impossible
* This operation could be slow in case of large number of plugins
*/
public fun <T : Any> Context.gather(
target: String,
type: KClass<out T>,
inherit: Boolean = true,
): Map<Name, T> = buildMap {
putAll(top(target, type))
plugins.forEach { plugin ->
plugin.top(target, type).forEach { (name, value) ->
val itemName = plugin.name + name
if (containsKey(itemName)) error("Name conflict during gather. An item with name $name could not be gathered from $plugin because key is already present.")
put(itemName, value)
}
}
if (inherit) {
parent?.gather(target, type, inherit)?.forEach {
//put all values from parent if they are not conflicting
if (!containsKey(it.key)) {
put(it.key, it.value)
}
}
}
}
public inline fun <reified T : Any> Context.gather(target: String, inherit: Boolean = true): Map<Name, T> =
gather(target, T::class, inherit)
/**
* Gather all content from context itself and its plugins in a form of sequence of name-value pairs. Ignores name conflicts.
*
* Adds parent context sequence as well if [inherit] is true
*/
@DFExperimental
public fun <T : Any> Context.gatherInSequence(
target: String,
type: KClass<out T>,
inherit: Boolean = true,
): Sequence<Map.Entry<Name, T>> = sequence {
yieldAll(top(target, type).entries)
plugins.forEach { plugin ->
yieldAll(plugin.top(target, type).mapKeys { plugin.name + it.key }.entries)
}
if (inherit) {
parent?.gather(target, type, inherit)?.let {
yieldAll(it.entries)
}
}
}
@DFExperimental
public inline fun <reified T : Any> Context.gatherInSequence(
target: String,
inherit: Boolean = true,
): Sequence<Map.Entry<Name, T>> = gatherInSequence(target, T::class, inherit)
public val <T> Sequence<Map.Entry<Name, T>>.values: Sequence<T> get() = map { it.value }

View File

@ -0,0 +1,35 @@
package space.kscience.dataforge.properties
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.ObservableMutableMeta
import space.kscience.dataforge.meta.transformations.MetaConverter
import space.kscience.dataforge.meta.transformations.nullableMetaToObject
import space.kscience.dataforge.meta.transformations.nullableObjectToMeta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.startsWith
@DFExperimental
public class MetaProperty<T : Any>(
public val meta: ObservableMutableMeta,
public val name: Name,
public val converter: MetaConverter<T>,
) : Property<T?> {
override var value: T?
get() = converter.nullableMetaToObject(meta[name])
set(value) {
meta[name] = converter.nullableObjectToMeta(value) ?: Meta.EMPTY
}
override fun onChange(owner: Any?, callback: (T?) -> Unit) {
meta.onChange(owner) { name ->
if (name.startsWith(this@MetaProperty.name)) callback(converter.nullableMetaToObject(this[name]))
}
}
override fun removeChangeListener(owner: Any?) {
meta.removeListener(owner)
}
}

View File

@ -0,0 +1,47 @@
package space.kscience.dataforge.properties
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import space.kscience.dataforge.misc.DFExperimental
@DFExperimental
public interface Property<T> {
public var value: T
public fun onChange(owner: Any? = null, callback: (T) -> Unit)
public fun removeChangeListener(owner: Any? = null)
}
@DFExperimental
@OptIn(ExperimentalCoroutinesApi::class)
public fun <T> Property<T>.toFlow(): StateFlow<T> = MutableStateFlow(value).also { stateFlow ->
onChange {
stateFlow.value = it
}
}
/**
* Reflect all changes in the [source] property onto this property. Does not reflect changes back.
*
* @return a mirroring job
*/
@DFExperimental
public fun <T> Property<T>.mirror(source: Property<T>) {
source.onChange(this) {
this.value = it
}
}
/**
* Bi-directional connection between properties
*/
@DFExperimental
public fun <T> Property<T>.bind(other: Property<T>) {
onChange(other) {
other.value = it
}
other.onChange {
this.value = it
}
}

View File

@ -0,0 +1,31 @@
package space.kscience.dataforge.properties
import space.kscience.dataforge.meta.Scheme
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.parseAsName
import space.kscience.dataforge.names.startsWith
import kotlin.reflect.KMutableProperty1
@DFExperimental
public fun <S : Scheme, T : Any> S.property(property: KMutableProperty1<S, T?>): Property<T?> =
object : Property<T?> {
override var value: T?
get() = property.get(this@property)
set(value) {
property.set(this@property, value)
}
override fun onChange(owner: Any?, callback: (T?) -> Unit) {
this@property.meta.onChange(this) { name ->
if (name.startsWith(property.name.parseAsName(true))) {
callback(property.get(this@property))
}
}
}
override fun removeChangeListener(owner: Any?) {
this@property.meta.removeListener(this@property)
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package space.kscience.dataforge.provider
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.parseAsName
import kotlin.jvm.JvmInline
/**
* Path interface.
*
*/
@JvmInline
public value class Path(public val tokens: List<PathToken>) : Iterable<PathToken> {
override fun iterator(): Iterator<PathToken> = tokens.iterator()
override fun toString(): String = tokens.joinToString(separator = PATH_SEGMENT_SEPARATOR)
public companion object {
public const val PATH_SEGMENT_SEPARATOR: String = "/"
public fun parse(path: String): Path = Path(path.split(PATH_SEGMENT_SEPARATOR).map { PathToken.parse(it) })
}
}
public val Path.length: Int get() = tokens.size
public val Path.head: PathToken? get() = tokens.firstOrNull()
/**
* Returns non-empty optional containing the chain without first segment in case of chain path.
*
* @return
*/
public val Path.tail: Path? get() = if (tokens.isEmpty()) null else Path(tokens.drop(1))
public operator fun Path.plus(path: Path): Path = Path(this.tokens + path.tokens)
public data class PathToken(val name: Name, val target: String? = null) {
override fun toString(): String = if (target == null) {
name.toString()
} else {
"$target$TARGET_SEPARATOR$name"
}
public companion object {
public const val TARGET_SEPARATOR: String = "::"
public fun parse(token: String, cache: Boolean = false): PathToken {
val target = token.substringBefore(TARGET_SEPARATOR, "")
val name = token.substringAfter(TARGET_SEPARATOR).parseAsName(cache)
if (target.contains("[")) TODO("target separators in queries are not supported")
return PathToken(name, target)
}
}
}
/**
* Represent this path token as full path
*/
public fun PathToken.asPath(): Path = Path(listOf(this))
/**
* Represent a name with optional [target] as a [Path]
*/
public fun Name.asPath(target: String? = null): Path = PathToken(this, target).asPath()
/**
* Build a path from given names using default targets
*/
public fun Path(vararg names: Name): Path = Path(names.map { PathToken(it) })
/**
* Use an array of [Name]-target pairs to construct segmented [Path]
*/
public fun Path(vararg tokens: Pair<Name, String?>): Path = Path(tokens.map { PathToken(it.first, it.second) })

View File

@ -0,0 +1,87 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package space.kscience.dataforge.provider
import space.kscience.dataforge.names.Name
import kotlin.reflect.KClass
import kotlin.reflect.safeCast
/**
* A marker utility interface for providers.
*
* @author Alexander Nozik
*/
public interface Provider {
/**
* Default target for this provider
*/
public val defaultTarget: String get() = ""
/**
* Default target for next chain segment
*/
public val defaultChainTarget: String get() = ""
/**
* A map of direct children for specific target
*/
public fun content(target: String): Map<Name, Any> = emptyMap()
}
public fun Provider.provide(path: Path, targetOverride: String? = null): Any? {
if (path.length == 0) throw IllegalArgumentException("Can't provide by empty path")
val first = path.first()
val target = targetOverride ?: first.target ?: defaultTarget
val res = content(target)[first.name] ?: return null
return when (path.length) {
1 -> res
else -> {
when (res) {
is Provider -> res.provide(path.tail!!, targetOverride = defaultChainTarget)
else -> throw IllegalStateException("Chain path not supported: child is not a provider")
}
}
}
}
/**
* Type checked provide
*/
public inline fun <reified T : Any> Provider.provide(path: String, targetOverride: String? = null): T? {
return provide(Path.parse(path), targetOverride) as? T
}
//
//inline fun <reified T : Any> Provider.provide(target: String, name: Name): T? {
// return provide(PathToken(name, target).toPath()) as? T
//}
//inline fun <reified T : Any> Provider.provide(target: String, name: String): T? =
// provide(target, name.toName())
/**
* Typed top level content
*/
public fun <T : Any> Provider.top(target: String, type: KClass<out T>): Map<Name, T> = content(target).mapValues {
type.safeCast(it.value) ?: error("The type of element ${it.value} is ${it.value::class} but $type is expected")
}
/**
* Typed top level content
*/
public inline fun <reified T : Any> Provider.top(target: String ): Map<Name, T> = top(target, T::class)

View File

@ -1,40 +0,0 @@
package hep.dataforge.context
import hep.dataforge.names.Name
import hep.dataforge.names.appendLeft
import hep.dataforge.names.toName
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class ContextTest {
class DummyPlugin : AbstractPlugin() {
override val tag get() = PluginTag("test")
override fun provideTop(target: String, name: Name): Any? {
return when (target) {
"test" -> return name
else -> super.provideTop(target, name)
}
}
override fun listNames(target: String): Sequence<Name> {
return when (target) {
"test" -> sequenceOf("a", "b", "c.d").map { it.toName() }
else -> super.listNames(target)
}
}
}
@Test
fun testPluginManager() {
Global.plugins.load(DummyPlugin())
val members = Global.content<Name>("test")
assertEquals(3, members.count())
members.forEach {
assertTrue{it.key == it.value.appendLeft("test")}
}
}
}

View File

@ -0,0 +1,33 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.appendFirst
import kotlin.test.Test
import kotlin.test.assertEquals
class ContextTest {
class DummyPlugin : AbstractPlugin() {
override val tag get() = PluginTag("test")
override fun content(target: String): Map<Name, Any> {
return when (target) {
"test" -> listOf("a", "b", "c.d").associate { Name.parse(it) to Name.parse(it) }
else -> emptyMap()
}
}
}
@Test
fun testPluginManager() {
val context = Context("test") {
plugin(DummyPlugin())
}
val members = context.gather<Name>("test")
assertEquals(3, members.count())
members.forEach {
assertEquals(it.key, it.value.appendFirst("test"))
}
}
}

View File

@ -0,0 +1,28 @@
package space.kscience.dataforge.properties
import space.kscience.dataforge.meta.Scheme
import space.kscience.dataforge.meta.SchemeSpec
import space.kscience.dataforge.meta.int
import space.kscience.dataforge.misc.DFExperimental
import kotlin.test.Test
import kotlin.test.assertEquals
internal class TestScheme : Scheme() {
var a by int()
var b by int()
companion object : SchemeSpec<TestScheme>(::TestScheme)
}
@DFExperimental
class MetaPropertiesTest {
@Test
fun testBinding() {
val scheme = TestScheme.empty()
val a = scheme.property(TestScheme::a)
val b = scheme.property(TestScheme::b)
a.bind(b)
scheme.a = 2
assertEquals(2, scheme.b)
assertEquals(2, b.value)
}
}

View File

@ -0,0 +1,14 @@
package space.kscience.dataforge.provider
import kotlin.test.Test
import kotlin.test.assertEquals
class PathTest {
@Test
fun testParse(){
val nameString = "a.b.c.d"
val pathString = "a.b/c.d"
assertEquals(1, Path.parse(nameString).length)
assertEquals(2, Path.parse(pathString).length)
}
}

View File

@ -1,16 +0,0 @@
package hep.dataforge.context
actual object PluginRepository {
private val factories: MutableSet<PluginFactory<*>> = HashSet()
actual fun register(factory: PluginFactory<*>) {
factories.add(factory)
}
/**
* List plugins available in the repository
*/
actual fun list(): Sequence<PluginFactory<*>> = factories.asSequence()
}

View File

@ -0,0 +1,32 @@
package space.kscience.dataforge.context
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.Name
public class ConsoleLogManager : AbstractPlugin(), LogManager {
override fun logger(name: Name): Logger = Logger { tag, body ->
val message: String = body.safe
when (tag) {
// TODO depends on https://youtrack.jetbrains.com/issue/KT-33595/
LogManager.DEBUG -> console.asDynamic().debug("[${context.name}] $name: $message")
LogManager.INFO -> console.info("[${context.name}] $name: $message")
LogManager.WARNING -> console.warn("[${context.name}] $name: $message")
LogManager.ERROR -> console.error("[${context.name}] $name: $message")
else -> console.log("[${context.name}] $name: $message")
}
}
override val defaultLogger: Logger = logger(Name.EMPTY)
override val tag: PluginTag get() = Companion.tag
public companion object : PluginFactory<ConsoleLogManager> {
override fun build(context: Context, meta: Meta): ConsoleLogManager = ConsoleLogManager()
override val tag: PluginTag = PluginTag(group = PluginTag.DATAFORGE_GROUP, name = "log.jsConsole")
}
}
internal actual fun getGlobalLoggerFactory(): PluginFactory<out LogManager> = ConsoleLogManager

View File

@ -0,0 +1,32 @@
package space.kscience.dataforge.properties
import org.w3c.dom.HTMLInputElement
import space.kscience.dataforge.misc.DFExperimental
@DFExperimental
public fun HTMLInputElement.bindValue(property: Property<String>) {
if (this.onchange != null) error("Input element already bound")
this.onchange = {
property.value = this.value
Unit
}
property.onChange(this) {
if (value != it) {
value = it
}
}
}
@DFExperimental
public fun HTMLInputElement.bindChecked(property: Property<Boolean>) {
if (this.onchange != null) error("Input element already bound")
this.onchange = {
property.value = this.checked
Unit
}
property.onChange(this) {
if (checked != it) {
checked = it
}
}
}

View File

@ -1,17 +0,0 @@
package hep.dataforge.context
actual object PluginRepository {
private val factories: MutableSet<PluginFactory<*>> = HashSet()
actual fun register(factory: PluginFactory<*>) {
factories.add(factory)
}
/**
* List plugins available in the repository
*/
actual fun list(): Sequence<PluginFactory<*>> =
factories.asSequence() + Global.services()
}

View File

@ -1,46 +0,0 @@
package hep.dataforge.provider
import hep.dataforge.context.Context
import hep.dataforge.context.content
import hep.dataforge.names.Name
import kotlin.reflect.KClass
import kotlin.reflect.full.findAnnotation
/**
*
*/
object Types {
operator fun get(cl: KClass<*>): String {
return cl.findAnnotation<Type>()?.id ?: cl.simpleName ?: ""
}
operator fun get(obj: Any): String {
return get(obj::class)
}
}
/**
* Provide an object with given name inferring target from its type using [Type] annotation
*/
inline fun <reified T : Any> Provider.provideByType(name: String): T? {
val target = Types[T::class]
return provide(target, name)
}
inline fun <reified T : Any> Provider.provideByType(name: Name): T? {
val target = Types[T::class]
return provide(target, name)
}
inline fun <reified T : Any> Provider.top(): Map<Name, T> {
val target = Types[T::class]
return listNames(target).associate { name ->
name to (provideByType<T>(name) ?: error("The element $name is declared but not provided"))
}
}
/**
* A sequences of all objects provided by plugins with given target and type
*/
inline fun <reified T : Any> Context.content(): Map<Name, T> = content<T>(Types[T::class])

View File

@ -13,30 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hep.dataforge.context
package space.kscience.dataforge.context
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.full.cast
class ClassLoaderPlugin(val classLoader: ClassLoader) : AbstractPlugin() {
public class ClassLoaderPlugin(private val classLoader: ClassLoader) : AbstractPlugin() {
override val tag: PluginTag = PluginTag("classLoader", PluginTag.DATAFORGE_GROUP)
private val serviceCache: MutableMap<Class<*>, ServiceLoader<*>> = HashMap()
fun <T : Any> services(type: KClass<T>): Sequence<T> {
public fun <T : Any> services(type: KClass<T>): Sequence<T> {
return serviceCache.getOrPut(type.java) { ServiceLoader.load(type.java, classLoader) }.asSequence()
.map { type.cast(it) }
}
companion object {
val DEFAULT = ClassLoaderPlugin(Global::class.java.classLoader)
public companion object {
public val DEFAULT: ClassLoaderPlugin = ClassLoaderPlugin(Global::class.java.classLoader)
}
}
val Context.classLoaderPlugin get() = this.plugins.get() ?: ClassLoaderPlugin.DEFAULT
public val Context.classLoaderPlugin: ClassLoaderPlugin get() = this.plugins.get() ?: ClassLoaderPlugin.DEFAULT
inline fun <reified T : Any> Context.services() = classLoaderPlugin.services(T::class)
public inline fun <reified T : Any> Context.services(): Sequence<T> = classLoaderPlugin.services(T::class)
//open class JVMContext(

View File

@ -0,0 +1,32 @@
package space.kscience.dataforge.context
import org.slf4j.LoggerFactory
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.Name
public class SlfLogManager : AbstractPlugin(), LogManager {
override fun logger(name: Name): Logger = Logger { tag, body ->
val logger = LoggerFactory.getLogger("[${context.name}] $name") //KotlinLogging.logger("[${context.name}] $name")
val message = body.safe
when (tag) {
LogManager.DEBUG -> logger.debug(message)
LogManager.INFO -> logger.info(message)
LogManager.WARNING -> logger.warn(message)
LogManager.ERROR -> logger.error(message)
else -> logger.trace(message)
}
}
override val defaultLogger: Logger = logger(Name.EMPTY)
override val tag: PluginTag get() = Companion.tag
public companion object : PluginFactory<SlfLogManager> {
override fun build(context: Context, meta: Meta): SlfLogManager = SlfLogManager()
override val tag: PluginTag = PluginTag(group = PluginTag.DATAFORGE_GROUP, name = "log.kotlinLogging")
}
}
internal actual fun getGlobalLoggerFactory(): PluginFactory<out LogManager> = SlfLogManager

View File

@ -0,0 +1,126 @@
/*
* Copyright 2018 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package space.kscience.dataforge.descriptors
//@MustBeDocumented
//annotation class Attribute(
// val key: String,
// val value: String
//)
//
//@MustBeDocumented
//annotation class Attributes(
// val attrs: Array<Attribute>
//)
//
//@MustBeDocumented
//annotation class ItemDef(
// val info: String = "",
// val multiple: Boolean = false,
// val required: Boolean = false
//)
//
//@Target(AnnotationTarget.PROPERTY)
//@MustBeDocumented
//annotation class ValueDef(
// val type: Array<ValueType> = [ValueType.STRING],
// val def: String = "",
// val allowed: Array<String> = [],
// val enumeration: KClass<*> = Any::class
//)
///**
// * Description text for meta property, node or whole object
// */
//@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class Description(val value: String)
//
///**
// * Annotation for value property which states that lists are expected
// */
//@Target(AnnotationTarget.PROPERTY)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class Multiple
//
///**
// * Descriptor target
// * The DataForge path to the resource containing the description. Following targets are supported:
// * 1. resource
// * 1. file
// * 1. class
// * 1. method
// * 1. property
// *
// *
// * Does not work if [type] is provided
// */
//@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class Descriptor(val value: String)
//
//
///**
// * Aggregator class for descriptor nodes
// */
//@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class DescriptorNodes(vararg val nodes: NodeDef)
//
///**
// * Aggregator class for descriptor values
// */
//@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class DescriptorValues(vararg val nodes: ValueDef)
//
///**
// * Alternative name for property descriptor declaration
// */
//@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class DescriptorName(val name: String)
//
//@Target(AnnotationTarget.PROPERTY)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class DescriptorValue(val def: ValueDef)
////TODO enter fields directly?
//
//@Target(AnnotationTarget.PROPERTY)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class ValueProperty(
// val name: String = "",
// val type: Array<ValueType> = arrayOf(ValueType.STRING),
// val multiple: Boolean = false,
// val def: String = "",
// val enumeration: KClass<*> = Any::class,
// val tags: Array<String> = emptyArray()
//)
//
//
//@Target(AnnotationTarget.PROPERTY)
//@Retention(AnnotationRetention.RUNTIME)
//@MustBeDocumented
//annotation class NodeProperty(val name: String = "")

View File

@ -0,0 +1,53 @@
package space.kscience.dataforge.descriptors
//inline fun <reified T : Scheme> T.buildDescriptor(): NodeDescriptor = NodeDescriptor {
// T::class.apply {
// findAnnotation<ItemDef>()?.let { def ->
// info = def.info
// required = def.required
// multiple = def.multiple
// }
// findAnnotation<Attribute>()?.let { attr ->
// attributes {
// this[attr.key] = attr.value.parseValue()
// }
// }
// findAnnotation<Attributes>()?.attrs?.forEach { attr ->
// attributes {
// this[attr.key] = attr.value.parseValue()
// }
// }
// }
// T::class.memberProperties.forEach { property ->
// val delegate = property.getDelegate(this@buildDescriptor)
//
// val descriptor: ItemDescriptor = when (delegate) {
// is ConfigurableDelegate -> buildPropertyDescriptor(property, delegate)
// is ReadWriteDelegateWrapper<*, *> -> {
// if (delegate.delegate is ConfigurableDelegate) {
// buildPropertyDescriptor(property, delegate.delegate as ConfigurableDelegate)
// } else {
// return@forEach
// }
// }
// else -> return@forEach
// }
// defineItem(property.name, descriptor)
// }
//}
//inline fun <T : Scheme, reified V : Any?> buildPropertyDescriptor(
// property: KProperty1<T, V>,
// delegate: ConfigurableDelegate
//): ItemDescriptor {
// when {
// V::class.isSubclassOf(Scheme::class) -> NodeDescriptor {
// default = delegate.default.node
// }
// V::class.isSubclassOf(Meta::class) -> NodeDescriptor {
// default = delegate.default.node
// }
//
// }
//}

View File

@ -0,0 +1,49 @@
package space.kscience.dataforge.provider
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginBuilder
import space.kscience.dataforge.context.gather
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.names.Name
import kotlin.reflect.KClass
import kotlin.reflect.full.findAnnotation
@DFExperimental
public val KClass<*>.dfId: String
get() = findAnnotation<DfId>()?.id ?: simpleName ?: ""
/**
* Provide an object with given name inferring target from its type using [DfId] annotation
*/
@DFExperimental
public inline fun <reified T : Any> Provider.provideByType(name: String): T? {
val target = T::class.dfId
return provide(target, name)
}
@DFExperimental
public inline fun <reified T : Any> Provider.top(): Map<Name, T> {
val target = T::class.dfId
return top(target)
}
/**
* All objects provided by plugins with given target and type
*/
@DFExperimental
public inline fun <reified T : Any> Context.gather(inherit: Boolean = true): Map<Name, T> =
gather<T>(T::class.dfId, inherit)
@DFExperimental
public inline fun <reified T : Any> PluginBuilder.provides(items: Map<Name, T>) {
provides(T::class.dfId, items)
}
@DFExperimental
public inline fun <reified T : Any> PluginBuilder.provides(vararg items: Named) {
provides(T::class.dfId, *items)
}

View File

@ -0,0 +1,4 @@
package space.kscience.dataforge.context
internal actual fun getGlobalLoggerFactory(): PluginFactory<out LogManager> = DefaultLogManager

23
dataforge-data/README.md Normal file
View File

@ -0,0 +1,23 @@
# Module dataforge-data
## Usage
## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-data:0.7.0`.
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-data:0.7.0")
}
```

View File

@ -0,0 +1,391 @@
public abstract interface class hep/dataforge/data/Action {
public abstract fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode;
public abstract fun isTerminal ()Z
}
public final class hep/dataforge/data/Action$DefaultImpls {
public static fun isTerminal (Lhep/dataforge/data/Action;)Z
}
public final class hep/dataforge/data/ActionEnv {
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Meta;)V
public final fun component1 ()Lhep/dataforge/names/Name;
public final fun component2 ()Lhep/dataforge/meta/Meta;
public final fun component3 ()Lhep/dataforge/meta/Meta;
public final fun copy (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/ActionEnv;
public static synthetic fun copy$default (Lhep/dataforge/data/ActionEnv;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/data/ActionEnv;
public fun equals (Ljava/lang/Object;)Z
public final fun getActionMeta ()Lhep/dataforge/meta/Meta;
public final fun getMeta ()Lhep/dataforge/meta/Meta;
public final fun getName ()Lhep/dataforge/names/Name;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class hep/dataforge/data/ActionKt {
public static final fun then (Lhep/dataforge/data/Action;Lhep/dataforge/data/Action;)Lhep/dataforge/data/Action;
}
public final class hep/dataforge/data/ComputationData : hep/dataforge/data/ComputationGoal, hep/dataforge/data/Data {
public fun <init> (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getMeta ()Lhep/dataforge/meta/Meta;
public fun getType ()Lkotlin/reflect/KClass;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}
public class hep/dataforge/data/ComputationGoal : hep/dataforge/data/Goal {
public fun <init> (Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getBlock ()Lkotlin/jvm/functions/Function2;
public fun getDependencies ()Ljava/util/Collection;
public final fun getResult ()Lkotlinx/coroutines/Deferred;
public fun reset ()V
public fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred;
}
public final class hep/dataforge/data/CoroutineMonitor : kotlin/coroutines/CoroutineContext$Element {
public static final field Companion Lhep/dataforge/data/CoroutineMonitor$Companion;
public fun <init> ()V
public final fun finish ()V
public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
public fun getKey ()Lkotlin/coroutines/CoroutineContext$Key;
public final fun getStatus ()Ljava/lang/String;
public final fun getTotalWork ()D
public final fun getWorkDone ()D
public fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
public final fun setStatus (Ljava/lang/String;)V
public final fun setTotalWork (D)V
public final fun setWorkDone (D)V
public final fun start ()V
}
public final class hep/dataforge/data/CoroutineMonitor$Companion : kotlin/coroutines/CoroutineContext$Key {
}
public final class hep/dataforge/data/CoroutineMonitorKt {
public static final fun getDependencies (Lkotlinx/coroutines/Job;)Ljava/util/Collection;
public static final fun getMonitor (Lkotlin/coroutines/CoroutineContext;)Lhep/dataforge/data/CoroutineMonitor;
public static final fun getMonitor (Lkotlinx/coroutines/CoroutineScope;)Lhep/dataforge/data/CoroutineMonitor;
public static final fun getProgress (Lkotlinx/coroutines/Job;)D
public static final fun getStatus (Lkotlinx/coroutines/Job;)Ljava/lang/String;
public static final fun getTotalWork (Lkotlinx/coroutines/Job;)D
public static final fun getWorkDone (Lkotlinx/coroutines/Job;)D
}
public abstract interface class hep/dataforge/data/Data : hep/dataforge/data/Goal, hep/dataforge/meta/MetaRepr {
public static final field Companion Lhep/dataforge/data/Data$Companion;
public static final field TYPE Ljava/lang/String;
public abstract fun getMeta ()Lhep/dataforge/meta/Meta;
public abstract fun getType ()Lkotlin/reflect/KClass;
public abstract fun toMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/data/Data$Companion {
public static final field TYPE Ljava/lang/String;
public final fun invoke (Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/Data;
public final fun invoke (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/Data;
public static synthetic fun invoke$default (Lhep/dataforge/data/Data$Companion;Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lhep/dataforge/data/Data;
public static synthetic fun invoke$default (Lhep/dataforge/data/Data$Companion;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lhep/dataforge/data/Data;
public final fun static (Ljava/lang/Object;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/Data;
public static synthetic fun static$default (Lhep/dataforge/data/Data$Companion;Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/data/Data;
}
public final class hep/dataforge/data/Data$DefaultImpls {
public static fun toMeta (Lhep/dataforge/data/Data;)Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/data/DataFilter : hep/dataforge/meta/Scheme {
public static final field Companion Lhep/dataforge/data/DataFilter$Companion;
public fun <init> ()V
public final fun getFrom ()Ljava/lang/String;
public final fun getPattern ()Ljava/lang/String;
public final fun getTo ()Ljava/lang/String;
public final fun setFrom (Ljava/lang/String;)V
public final fun setPattern (Ljava/lang/String;)V
public final fun setTo (Ljava/lang/String;)V
}
public final class hep/dataforge/data/DataFilter$Companion : hep/dataforge/meta/SchemeSpec {
}
public final class hep/dataforge/data/DataFilterKt {
public static final fun filter (Lhep/dataforge/data/DataNode;Lhep/dataforge/data/DataFilter;)Lhep/dataforge/data/DataNode;
public static final fun filter (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode;
public static final fun filter (Lhep/dataforge/data/DataNode;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/data/DataNode;
}
public abstract class hep/dataforge/data/DataItem : hep/dataforge/meta/MetaRepr {
public abstract fun getMeta ()Lhep/dataforge/meta/Meta;
public abstract fun getType ()Lkotlin/reflect/KClass;
}
public final class hep/dataforge/data/DataItem$Leaf : hep/dataforge/data/DataItem {
public fun <init> (Lhep/dataforge/data/Data;)V
public final fun getData ()Lhep/dataforge/data/Data;
public fun getMeta ()Lhep/dataforge/meta/Meta;
public fun getType ()Lkotlin/reflect/KClass;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/data/DataItem$Node : hep/dataforge/data/DataItem {
public fun <init> (Lhep/dataforge/data/DataNode;)V
public fun getMeta ()Lhep/dataforge/meta/Meta;
public final fun getNode ()Lhep/dataforge/data/DataNode;
public fun getType ()Lkotlin/reflect/KClass;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/data/DataJVMKt {
public static final fun canCast (Lhep/dataforge/data/DataItem;Lkotlin/reflect/KClass;)Z
public static final fun cast (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data;
public static final fun cast (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataNode;
public static final fun ensureType (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)V
public static final fun filterIsInstance (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data;
public static final fun filterIsInstance (Lhep/dataforge/data/DataItem;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataItem;
public static final fun filterIsInstance (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataNode;
public static final fun get (Lhep/dataforge/data/Data;)Ljava/lang/Object;
public static final fun upcast (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data;
}
public final class hep/dataforge/data/DataKt {
public static final fun map (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Data;
public static synthetic fun map$default (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Data;
public static final fun reduce (Ljava/util/Map;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/ComputationData;
public static synthetic fun reduce$default (Ljava/util/Map;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/ComputationData;
}
public abstract interface class hep/dataforge/data/DataNode : hep/dataforge/meta/MetaRepr {
public static final field Companion Lhep/dataforge/data/DataNode$Companion;
public static final field TYPE Ljava/lang/String;
public abstract fun getItems ()Ljava/util/Map;
public abstract fun getMeta ()Lhep/dataforge/meta/Meta;
public abstract fun getType ()Lkotlin/reflect/KClass;
public abstract fun toMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/data/DataNode$Companion {
public static final field TYPE Ljava/lang/String;
public final fun builder (Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataTreeBuilder;
}
public final class hep/dataforge/data/DataNode$DefaultImpls {
public static fun toMeta (Lhep/dataforge/data/DataNode;)Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/data/DataNodeKt {
public static final fun dataSequence (Lhep/dataforge/data/DataNode;)Lkotlin/sequences/Sequence;
public static final fun filter (Lhep/dataforge/data/DataNode;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/DataNode;
public static final fun first (Lhep/dataforge/data/DataNode;)Lhep/dataforge/data/Data;
public static final fun get (Lhep/dataforge/data/DataNode;Lhep/dataforge/names/Name;)Lhep/dataforge/data/DataItem;
public static final fun get (Lhep/dataforge/data/DataNode;Ljava/lang/String;)Lhep/dataforge/data/DataItem;
public static final fun getData (Lhep/dataforge/data/DataItem;)Lhep/dataforge/data/Data;
public static final fun getNode (Lhep/dataforge/data/DataItem;)Lhep/dataforge/data/DataNode;
public static final fun itemSequence (Lhep/dataforge/data/DataNode;)Lkotlin/sequences/Sequence;
public static final fun iterator (Lhep/dataforge/data/DataNode;)Ljava/util/Iterator;
public static final fun join (Lhep/dataforge/data/DataNode;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun startAll (Lhep/dataforge/data/DataNode;Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Job;
}
public final class hep/dataforge/data/DataTree : hep/dataforge/data/DataNode {
public fun getItems ()Ljava/util/Map;
public fun getMeta ()Lhep/dataforge/meta/Meta;
public fun getType ()Lkotlin/reflect/KClass;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/data/DataTreeBuilder {
public fun <init> (Lkotlin/reflect/KClass;)V
public final fun build ()Lhep/dataforge/data/DataTree;
public final fun getType ()Lkotlin/reflect/KClass;
public final fun meta (Lhep/dataforge/meta/Meta;)V
public final fun meta (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MetaBuilder;
public final fun put (Ljava/lang/String;Lhep/dataforge/data/Data;)V
public final fun put (Ljava/lang/String;Lhep/dataforge/data/DataItem;)V
public final fun put (Ljava/lang/String;Lhep/dataforge/data/DataNode;)V
public final fun put (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun set (Lhep/dataforge/names/Name;Lhep/dataforge/data/Data;)V
public final fun set (Lhep/dataforge/names/Name;Lhep/dataforge/data/DataItem;)V
public final fun set (Lhep/dataforge/names/Name;Lhep/dataforge/data/DataNode;)V
public final fun set (Lhep/dataforge/names/Name;Lhep/dataforge/data/DataTreeBuilder;)V
public final fun set (Lhep/dataforge/names/NameToken;Lhep/dataforge/data/Data;)V
public final fun set (Lhep/dataforge/names/NameToken;Lhep/dataforge/data/DataTreeBuilder;)V
public final fun update (Lhep/dataforge/data/DataNode;)V
}
public final class hep/dataforge/data/DataTreeBuilderKt {
public static final fun DataTree (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/data/DataTree;
public static final fun builder (Lhep/dataforge/data/DataNode;)Lhep/dataforge/data/DataTreeBuilder;
public static final fun datum (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/data/Data;)V
public static final fun datum (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Lhep/dataforge/data/Data;)V
public static final fun node (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/data/DataNode;)V
public static final fun node (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Lhep/dataforge/data/DataNode;)V
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)V
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
}
public final class hep/dataforge/data/Dependencies : kotlin/coroutines/CoroutineContext$Element {
public static final field Companion Lhep/dataforge/data/Dependencies$Companion;
public fun <init> (Ljava/util/Collection;)V
public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
public fun getKey ()Lkotlin/coroutines/CoroutineContext$Key;
public final fun getValues ()Ljava/util/Collection;
public fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
}
public final class hep/dataforge/data/Dependencies$Companion : kotlin/coroutines/CoroutineContext$Key {
}
public final class hep/dataforge/data/FragmentRule {
public field result Lkotlin/jvm/functions/Function2;
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaBuilder;)V
public final fun getMeta ()Lhep/dataforge/meta/MetaBuilder;
public final fun getName ()Lhep/dataforge/names/Name;
public final fun getResult ()Lkotlin/jvm/functions/Function2;
public final fun result (Lkotlin/jvm/functions/Function2;)V
public final fun setMeta (Lhep/dataforge/meta/MetaBuilder;)V
public final fun setResult (Lkotlin/jvm/functions/Function2;)V
}
public abstract interface class hep/dataforge/data/Goal {
public static final field Companion Lhep/dataforge/data/Goal$Companion;
public abstract fun getDependencies ()Ljava/util/Collection;
public abstract fun getResult ()Lkotlinx/coroutines/Deferred;
public abstract fun reset ()V
public abstract fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred;
}
public final class hep/dataforge/data/Goal$Companion {
}
public final class hep/dataforge/data/GoalKt {
public static final fun await (Lhep/dataforge/data/Goal;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final fun isComplete (Lhep/dataforge/data/Goal;)Z
public static final fun map (Lhep/dataforge/data/Goal;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Goal;
public static synthetic fun map$default (Lhep/dataforge/data/Goal;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Goal;
public static final fun reduce (Ljava/util/Collection;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Goal;
public static final fun reduce (Ljava/util/Map;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Goal;
public static synthetic fun reduce$default (Ljava/util/Collection;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Goal;
public static synthetic fun reduce$default (Ljava/util/Map;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Goal;
}
public abstract interface class hep/dataforge/data/GroupRule {
public static final field Companion Lhep/dataforge/data/GroupRule$Companion;
public abstract fun invoke (Lhep/dataforge/data/DataNode;)Ljava/util/Map;
}
public final class hep/dataforge/data/GroupRule$Companion {
public final fun byMeta (Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/GroupRule;
public final fun byValue (Ljava/lang/String;Ljava/lang/String;)Lhep/dataforge/data/GroupRule;
}
public final class hep/dataforge/data/JoinGroup {
public field result Lkotlin/jvm/functions/Function3;
public fun <init> (Ljava/lang/String;Lhep/dataforge/data/DataNode;)V
public final fun getMeta ()Lhep/dataforge/meta/MetaBuilder;
public final fun getName ()Ljava/lang/String;
public final fun getResult ()Lkotlin/jvm/functions/Function3;
public final fun result (Lkotlin/jvm/functions/Function3;)V
public final fun setMeta (Lhep/dataforge/meta/MetaBuilder;)V
public final fun setName (Ljava/lang/String;)V
public final fun setResult (Lkotlin/jvm/functions/Function3;)V
}
public final class hep/dataforge/data/MapAction : hep/dataforge/data/Action {
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode;
public fun isTerminal ()Z
}
public final class hep/dataforge/data/MapActionBuilder {
public field result Lkotlin/jvm/functions/Function3;
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaBuilder;Lhep/dataforge/meta/Meta;)V
public final fun getActionMeta ()Lhep/dataforge/meta/Meta;
public final fun getMeta ()Lhep/dataforge/meta/MetaBuilder;
public final fun getName ()Lhep/dataforge/names/Name;
public final fun getResult ()Lkotlin/jvm/functions/Function3;
public final fun result (Lkotlin/jvm/functions/Function3;)V
public final fun setMeta (Lhep/dataforge/meta/MetaBuilder;)V
public final fun setName (Lhep/dataforge/names/Name;)V
public final fun setResult (Lkotlin/jvm/functions/Function3;)V
}
public final class hep/dataforge/data/NamedData : hep/dataforge/data/Data {
public fun <init> (Ljava/lang/String;Lhep/dataforge/data/Data;)V
public fun getDependencies ()Ljava/util/Collection;
public fun getMeta ()Lhep/dataforge/meta/Meta;
public final fun getName ()Ljava/lang/String;
public fun getResult ()Lkotlinx/coroutines/Deferred;
public fun getType ()Lkotlin/reflect/KClass;
public fun reset ()V
public fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/data/ReduceAction : hep/dataforge/data/Action {
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode;
public fun isTerminal ()Z
}
public final class hep/dataforge/data/ReduceActionKt {
public static final fun get (Ljava/util/Map;Ljava/lang/String;)Ljava/lang/Object;
}
public final class hep/dataforge/data/ReduceGroupBuilder {
public fun <init> (Lhep/dataforge/meta/Meta;)V
public final fun byValue (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun byValue$default (Lhep/dataforge/data/ReduceGroupBuilder;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public final fun getActionMeta ()Lhep/dataforge/meta/Meta;
public final fun group (Ljava/lang/String;Lhep/dataforge/data/DataFilter;Lkotlin/jvm/functions/Function1;)V
public final fun group (Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)V
public final fun result (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)V
}
public final class hep/dataforge/data/SplitAction : hep/dataforge/data/Action {
public fun <init> (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode;
public fun isTerminal ()Z
}
public final class hep/dataforge/data/SplitBuilder {
public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V
public final fun fragment (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun getMeta ()Lhep/dataforge/meta/Meta;
public final fun getName ()Lhep/dataforge/names/Name;
}
public final class hep/dataforge/data/StaticData : hep/dataforge/data/StaticGoal, hep/dataforge/data/Data {
public fun <init> (Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V
public synthetic fun <init> (Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getMeta ()Lhep/dataforge/meta/Meta;
public fun getType ()Lkotlin/reflect/KClass;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}
public class hep/dataforge/data/StaticGoal : hep/dataforge/data/Goal {
public fun <init> (Ljava/lang/Object;)V
public fun getDependencies ()Ljava/util/Collection;
public fun getResult ()Lkotlinx/coroutines/Deferred;
public final fun getValue ()Ljava/lang/Object;
public fun reset ()V
public fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred;
}
public final class hep/dataforge/data/TypeFilteredDataNode : hep/dataforge/data/DataNode {
public fun <init> (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)V
public fun getItems ()Ljava/util/Map;
public fun getMeta ()Lhep/dataforge/meta/Meta;
public final fun getOrigin ()Lhep/dataforge/data/DataNode;
public fun getType ()Lkotlin/reflect/KClass;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}

View File

@ -1,31 +1,18 @@
plugins {
`npm-multiplatform`
id("space.kscience.gradle.mpp")
}
val coroutinesVersion: String = Versions.coroutinesVersion
kotlin {
kscience{
jvm()
js()
sourceSets {
val commonMain by getting{
dependencies {
api(project(":dataforge-meta"))
api(kotlin("reflect"))
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion")
}
}
val jvmMain by getting{
dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
}
}
val jsMain by getting{
dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion")
}
}
native()
useCoroutines()
dependencies {
api(project(":dataforge-meta"))
api(kotlin("reflect"))
}
}
}
readme{
maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
}

View File

@ -1,52 +0,0 @@
package hep.dataforge.data
import hep.dataforge.meta.Meta
import hep.dataforge.names.Name
/**
* A simple data transformation on a data node
*/
interface Action<in T : Any, out R : Any> {
/**
* Transform the data in the node, producing a new node. By default it is assumed that all calculations are lazy
* so not actual computation is started at this moment
*/
operator fun invoke(node: DataNode<T>, meta: Meta): DataNode<R>
/**
* Terminal action is the one that could not be invoked lazily and requires some kind of blocking computation to invoke
*/
val isTerminal: Boolean get() = false
}
/**
* Action composition. The result is terminal if one of its parts is terminal
*/
infix fun <T : Any, I : Any, R : Any> Action<T, I>.then(action: Action<I, R>): Action<T, R> {
// TODO introduce composite action and add optimize by adding action to the list
return object : Action<T, R> {
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
return action(this@then.invoke(node, meta), meta)
}
override val isTerminal: Boolean
get() = this@then.isTerminal || action.isTerminal
}
}
///**
// * An action that performs the same transformation on each of input data nodes. Null results are ignored.
// * The transformation is non-suspending because it is lazy.
// */
//class PipeAction<in T : Any, out R : Any>(val transform: (Name, Data<T>, Meta) -> Data<R>?) : Action<T, R> {
// override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> = DataNode.build {
// node.data().forEach { (name, data) ->
// val res = transform(name, data, meta)
// if (res != null) {
// set(name, res)
// }
// }
// }
//}

View File

@ -1,69 +0,0 @@
package hep.dataforge.data
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaRepr
import kotlinx.coroutines.CoroutineScope
import kotlin.reflect.KClass
/**
* A data element characterized by its meta
*/
interface Data<out T : Any> : MetaRepr {
/**
* Type marker for the data. The type is known before the calculation takes place so it could be checked.
*/
val type: KClass<out T>
/**
* Meta for the data
*/
val meta: Meta
/**
* Lazy data value
*/
val goal: Goal<T>
override fun toMeta(): Meta = meta
companion object {
const val TYPE = "data"
fun <T : Any> of(type: KClass<out T>, goal: Goal<T>, meta: Meta): Data<T> = DataImpl(type, goal, meta)
inline fun <reified T : Any> of(goal: Goal<T>, meta: Meta): Data<T> = of(T::class, goal, meta)
fun <T : Any> of(name: String, type: KClass<out T>, goal: Goal<T>, meta: Meta): Data<T> =
NamedData(name, of(type, goal, meta))
inline fun <reified T : Any> of(name: String, goal: Goal<T>, meta: Meta): Data<T> =
of(name, T::class, goal, meta)
fun <T : Any> static(scope: CoroutineScope, value: T, meta: Meta): Data<T> =
DataImpl(value::class, Goal.static(scope, value), meta)
}
}
/**
* Upcast a [Data] to a supertype
*/
inline fun <reified R : Any, reified T : R> Data<T>.cast(): Data<R> {
return Data.of(R::class, goal, meta)
}
fun <R : Any, T : R> Data<T>.cast(type: KClass<R>): Data<R> {
return Data.of(type, goal, meta)
}
suspend fun <T : Any> Data<T>.await(): T = goal.await()
/**
* Generic Data implementation
*/
private class DataImpl<out T : Any>(
override val type: KClass<out T>,
override val goal: Goal<T>,
override val meta: Meta
) : Data<T>
class NamedData<out T : Any>(val name: String, data: Data<T>) : Data<T> by data

View File

@ -1,46 +0,0 @@
package hep.dataforge.data
import hep.dataforge.meta.*
import hep.dataforge.names.toName
class DataFilter(override val config: Config) : Specific {
var from by string()
var to by string()
var pattern by string("*.")
// val prefix by string()
// val suffix by string()
companion object : Specification<DataFilter> {
override fun wrap(config: Config): DataFilter = DataFilter(config)
}
}
/**
* Apply meta-based filter to given data node
*/
fun <T : Any> DataNode<T>.filter(filter: DataFilter): DataNode<T> {
val sourceNode = filter.from?.let { getNode(it.toName()) } ?: this@filter
val regex = filter.pattern.toRegex()
val targetNode = DataTreeBuilder(type).apply {
sourceNode.data().forEach { (name, data) ->
if (name.toString().matches(regex)) {
this[name] = data
}
}
}
return filter.to?.let {
DataTreeBuilder(type).apply { this[it.toName()] = targetNode }.build()
} ?: targetNode.build()
}
/**
* Filter data using [DataFilter] specification
*/
fun <T : Any> DataNode<T>.filter(filter: Meta): DataNode<T> = filter(DataFilter.wrap(filter))
/**
* Filter data using [DataFilter] builder
*/
fun <T : Any> DataNode<T>.filter(filterBuilder: DataFilter.() -> Unit): DataNode<T> =
filter(DataFilter.build(filterBuilder))

View File

@ -1,216 +0,0 @@
package hep.dataforge.data
import hep.dataforge.names.*
import kotlin.reflect.KClass
/**
* A tree-like data structure grouped into the node. All data inside the node must inherit its type
*/
interface DataNode<out T : Any> {
/**
* The minimal common ancestor to all data in the node
*/
val type: KClass<out T>
/**
* Get the specific data if it exists
*/
operator fun get(name: Name): Data<T>?
/**
* Get a subnode with given name if it exists.
*/
fun getNode(name: Name): DataNode<T>?
/**
* Walk the tree upside down and provide all data nodes with full names
*/
fun data(): Sequence<Pair<Name, Data<T>>>
/**
* A sequence of all nodes in the tree walking upside down, excluding self
*/
fun nodes(): Sequence<Pair<Name, DataNode<T>>>
operator fun iterator(): Iterator<Pair<Name, Data<T>>> = data().iterator()
companion object {
const val TYPE = "dataNode"
fun <T : Any> build(type: KClass<out T>, block: DataTreeBuilder<T>.() -> Unit) =
DataTreeBuilder<T>(type).apply(block).build()
fun <T : Any> builder(type: KClass<out T>) = DataTreeBuilder(type)
}
}
internal sealed class DataTreeItem<out T : Any> {
class Node<out T : Any>(val tree: DataTree<T>) : DataTreeItem<T>()
class Value<out T : Any>(val value: Data<T>) : DataTreeItem<T>()
}
class DataTree<out T : Any> internal constructor(
override val type: KClass<out T>,
private val items: Map<NameToken, DataTreeItem<T>>
) : DataNode<T> {
//TODO add node-level meta?
override fun get(name: Name): Data<T>? = when (name.length) {
0 -> error("Empty name")
1 -> (items[name.first()] as? DataTreeItem.Value)?.value
else -> getNode(name.first()!!.asName())?.get(name.cutFirst())
}
override fun getNode(name: Name): DataTree<T>? = when (name.length) {
0 -> this
1 -> (items[name.first()] as? DataTreeItem.Node)?.tree
else -> getNode(name.first()!!.asName())?.getNode(name.cutFirst())
}
override fun data(): Sequence<Pair<Name, Data<T>>> {
return sequence {
items.forEach { (head, tree) ->
when (tree) {
is DataTreeItem.Value -> yield(head.asName() to tree.value)
is DataTreeItem.Node -> {
val subSequence =
tree.tree.data().map { (name, data) -> (head.asName() + name) to data }
yieldAll(subSequence)
}
}
}
}
}
override fun nodes(): Sequence<Pair<Name, DataNode<T>>> {
return sequence {
items.forEach { (head, tree) ->
if (tree is DataTreeItem.Node) {
yield(head.asName() to tree.tree)
val subSequence =
tree.tree.nodes().map { (name, node) -> (head.asName() + name) to node }
yieldAll(subSequence)
}
}
}
}
}
private sealed class DataTreeBuilderItem<out T : Any> {
class Node<T : Any>(val tree: DataTreeBuilder<T>) : DataTreeBuilderItem<T>()
class Value<T : Any>(val value: Data<T>) : DataTreeBuilderItem<T>()
}
/**
* A builder for a DataTree.
*/
class DataTreeBuilder<T : Any>(private val type: KClass<out T>) {
private val map = HashMap<NameToken, DataTreeBuilderItem<T>>()
operator fun set(token: NameToken, node: DataTreeBuilder<T>) {
if (map.containsKey(token)) error("Tree entry with name $token is not empty")
map[token] = DataTreeBuilderItem.Node(node)
}
operator fun set(token: NameToken, data: Data<T>) {
if (map.containsKey(token)) error("Tree entry with name $token is not empty")
map[token] = DataTreeBuilderItem.Value(data)
}
private fun buildNode(token: NameToken): DataTreeBuilder<T> {
return if (!map.containsKey(token)) {
DataTreeBuilder<T>(type).also { map[token] = DataTreeBuilderItem.Node(it) }
} else {
(map[token] as? DataTreeBuilderItem.Node ?: error("The node with name $token is occupied by leaf")).tree
}
}
private fun buildNode(name: Name): DataTreeBuilder<T> {
return when (name.length) {
0 -> this
1 -> buildNode(name.first()!!)
else -> buildNode(name.first()!!).buildNode(name.cutFirst())
}
}
operator fun set(name: Name, data: Data<T>) {
when (name.length) {
0 -> error("Can't add data with empty name")
1 -> set(name.first()!!, data)
2 -> buildNode(name.cutLast())[name.last()!!] = data
}
}
operator fun set(name: Name, node: DataTreeBuilder<T>) {
when (name.length) {
0 -> error("Can't add data with empty name")
1 -> set(name.first()!!, node)
2 -> buildNode(name.cutLast())[name.last()!!] = node
}
}
operator fun set(name: Name, node: DataNode<T>) = set(name, node.builder())
/**
* Append data to node
*/
infix fun String.to(data: Data<T>) = set(toName(), data)
/**
* Append node
*/
infix fun String.to(node: DataNode<T>) = set(toName(), node)
/**
* Build and append node
*/
infix fun String.to(block: DataTreeBuilder<T>.() -> Unit) = set(toName(), DataTreeBuilder<T>(type).apply(block))
fun update(node: DataNode<T>){
node.data().forEach {
//TODO check if the place is occupied
this[it.first] = it.second
}
}
fun build(): DataTree<T> {
val resMap = map.mapValues { (_, value) ->
when (value) {
is DataTreeBuilderItem.Value -> DataTreeItem.Value(value.value)
is DataTreeBuilderItem.Node -> DataTreeItem.Node(value.tree.build())
}
}
return DataTree(type, resMap)
}
}
/**
* Generate a mutable builder from this node. Node content is not changed
*/
fun <T : Any> DataNode<T>.builder(): DataTreeBuilder<T> = DataTreeBuilder(type).apply {
data().forEach { (name, data) -> this[name] = data }
}
/**
* Start computation for all goals in data node
*/
fun DataNode<*>.startAll() = data().forEach { (_, data) -> data.goal.start() }
fun <T : Any> DataNode<T>.filter(predicate: (Name, Data<T>) -> Boolean): DataNode<T> = DataNode.build(type) {
data().forEach { (name, data) ->
if (predicate(name, data)) {
this[name] = data
}
}
}
fun <T: Any> DataNode<T>.first(): Data<T> = data().first().second
/**
* Check that node is compatible with given type meaning that each element could be cast to the type
*/
expect fun DataNode<*>.checkType(type: KClass<*>)
//fun <T : Any, R: T> DataNode<T>.filterIsInstance(type: KClass<R>): DataNode<R> = filter{_,data -> type.}

View File

@ -1,131 +0,0 @@
package hep.dataforge.data
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* A special deferred with explicit dependencies and some additional information like progress and unique id
*/
interface Goal<out T> : Deferred<T>, CoroutineScope {
val scope: CoroutineScope
override val coroutineContext get() = scope.coroutineContext
val dependencies: Collection<Goal<*>>
val totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0)
val workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0)
val status: String get() = monitor?.status ?: ""
val progress: Double get() = workDone / totalWork
companion object {
/**
* Create goal wrapping static value. This goal is always completed
*/
fun <T> static(scope: CoroutineScope, value: T): Goal<T> =
StaticGoalImpl(scope, CompletableDeferred(value))
}
}
/**
* A monitor of goal state that could be accessed only form inside the goal
*/
class GoalMonitor : CoroutineContext.Element {
override val key: CoroutineContext.Key<*> get() = GoalMonitor
var totalWork: Double = 1.0
var workDone: Double = 0.0
var status: String = ""
/**
* Mark the goal as started
*/
fun start() {
}
/**
* Mark the goal as completed
*/
fun finish() {
workDone = totalWork
}
companion object : CoroutineContext.Key<GoalMonitor>
}
val CoroutineScope.monitor: GoalMonitor? get() = coroutineContext[GoalMonitor]
private class GoalImpl<T>(
override val scope: CoroutineScope,
override val dependencies: Collection<Goal<*>>,
deferred: Deferred<T>
) : Goal<T>, Deferred<T> by deferred
private class StaticGoalImpl<T>(override val scope: CoroutineScope, deferred: CompletableDeferred<T>) : Goal<T>,
Deferred<T> by deferred {
override val dependencies: Collection<Goal<*>> get() = emptyList()
override val status: String get() = ""
override val totalWork: Double get() = 0.0
override val workDone: Double get() = 0.0
}
/**
* Create a new [Goal] with given [dependencies] and execution [block]. The block takes monitor as parameter.
* The goal block runs in a supervised scope, meaning that when it fails, it won't affect external scope.
*
* **Important:** Unlike regular deferred, the [Goal] is started lazily, so the actual calculation is called only when result is requested.
*/
fun <R> CoroutineScope.createGoal(
dependencies: Collection<Goal<*>>,
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.() -> R
): Goal<R> {
val deferred = async(context + GoalMonitor(), start = CoroutineStart.LAZY) {
dependencies.forEach { it.start() }
monitor?.start()
//Running in supervisor scope in order to allow manual error handling
return@async supervisorScope {
block().also {
monitor?.finish()
}
}
}
return GoalImpl(this, dependencies, deferred)
}
/**
* Create a one-to-one goal based on existing goal
*/
fun <T, R> Goal<T>.pipe(
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.(T) -> R
): Goal<R> = createGoal(listOf(this), context) { block(await()) }
/**
* Create a joining goal.
* @param scope the scope for resulting goal. By default use first goal in list
*/
fun <T, R> Collection<Goal<T>>.join(
scope: CoroutineScope = first(),
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.(Collection<T>) -> R
): Goal<R> = scope.createGoal(this, context) {
block(map { it.await() })
}
/**
* A joining goal for a map
* @param K type of the map key
* @param T type of the input goal
* @param R type of the result goal
*/
fun <K, T, R> Map<K, Goal<T>>.join(
scope: CoroutineScope = values.first(),
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.(Map<K, T>) -> R
): Goal<R> = scope.createGoal(this.values, context) {
block(mapValues { it.value.await() })
}

View File

@ -1,75 +0,0 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hep.dataforge.data
import hep.dataforge.meta.Meta
import hep.dataforge.meta.get
import hep.dataforge.meta.string
interface GroupRule {
operator fun <T : Any> invoke(node: DataNode<T>): Map<String, DataNode<T>>
}
/**
* The class to builder groups of content with annotation defined rules
*
* @author Alexander Nozik
*/
object GroupBuilder {
/**
* Create grouping rule that creates groups for different values of value
* field with name [key]
*
* @param key
* @param defaultTagValue
* @return
*/
fun byValue(key: String, defaultTagValue: String): GroupRule = object :
GroupRule {
override fun <T : Any> invoke(node: DataNode<T>): Map<String, DataNode<T>> {
val map = HashMap<String, DataTreeBuilder<T>>()
node.data().forEach { (name, data) ->
val tagValue = data.meta[key]?.string ?: defaultTagValue
map.getOrPut(tagValue) { DataNode.builder(node.type) }[name] = data
}
return map.mapValues { it.value.build() }
}
}
// @ValueDef(key = "byValue", required = true, info = "The name of annotation value by which grouping should be made")
// @ValueDef(
// key = "defaultValue",
// def = "default",
// info = "Default value which should be used for content in which the grouping value is not presented"
// )
fun byMeta(config: Meta): GroupRule {
//TODO expand grouping options
return config["byValue"]?.string?.let {
byValue(
it,
config["defaultValue"]?.string ?: "default"
)
}
?: object : GroupRule {
override fun <T : Any> invoke(node: DataNode<T>): Map<String, DataNode<T>> = mapOf("" to node)
}
}
}

View File

@ -1,111 +0,0 @@
package hep.dataforge.data
import hep.dataforge.meta.Laminate
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.builder
import hep.dataforge.names.Name
import hep.dataforge.names.toName
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KClass
class JoinGroup<T : Any, R : Any>(var name: String, internal val node: DataNode<T>) {
var meta: MetaBuilder = MetaBuilder()
lateinit var result: suspend ActionEnv.(Map<Name, T>) -> R
fun result(f: suspend ActionEnv.(Map<Name, T>) -> R) {
this.result = f;
}
}
class JoinGroupBuilder<T : Any, R : Any>(val actionMeta: Meta) {
private val groupRules: MutableList<(DataNode<T>) -> List<JoinGroup<T, R>>> = ArrayList();
/**
* introduce grouping by value name
*/
fun byValue(tag: String, defaultTag: String = "@default", action: JoinGroup<T, R>.() -> Unit) {
groupRules += { node ->
GroupBuilder.byValue(tag, defaultTag).invoke(node).map {
JoinGroup<T, R>(it.key, it.value).apply(action)
}
}
}
/**
* Add a single fixed group to grouping rules
*/
fun group(groupName: String, filter: DataFilter, action: JoinGroup<T, R>.() -> Unit) {
groupRules += { node ->
listOf(
JoinGroup<T, R>(groupName, node.filter(filter)).apply(action)
)
}
}
fun group(groupName: String, filter: (Name, Data<T>) -> Boolean, action: JoinGroup<T, R>.() -> Unit) {
groupRules += { node ->
listOf(
JoinGroup<T, R>(groupName, node.filter(filter)).apply(action)
)
}
}
/**
* Apply transformation to the whole node
*/
fun result(resultName: String, f: suspend ActionEnv.(Map<Name, T>) -> R) {
groupRules += { node ->
listOf(JoinGroup<T, R>(resultName, node).apply { result(f) })
}
}
internal fun buildGroups(input: DataNode<T>): List<JoinGroup<T, R>> {
return groupRules.flatMap { it.invoke(input) }
}
}
/**
* The same rules as for KPipe
*/
class JoinAction<T : Any, R : Any>(
val inputType: KClass<T>,
val outputType: KClass<R>,
val context: CoroutineContext = EmptyCoroutineContext,
private val action: JoinGroupBuilder<T, R>.() -> Unit
) : Action<T, R> {
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
node.checkType(inputType)
return DataNode.build(outputType) {
JoinGroupBuilder<T, R>(meta).apply(action).buildGroups(node).forEach { group ->
val laminate = Laminate(group.meta, meta)
val goalMap: Map<Name, Goal<T>> = group.node
.data()
.associate { it.first to it.second.goal }
val groupName: String = group.name;
val env = ActionEnv(groupName.toName(), laminate.builder())
val goal = goalMap.join(context = context) { group.result.invoke(env, it) }
val res = Data.of(outputType, goal, env.meta)
set(env.name, res)
}
}
}
}
operator fun <T> Map<Name,T>.get(name:String) = get(name.toName())

View File

@ -1,65 +0,0 @@
package hep.dataforge.data
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KClass
class ActionEnv(val name: Name, val meta: Meta)
/**
* Action environment
*/
class PipeBuilder<T, R>(var name: Name, var meta: MetaBuilder) {
lateinit var result: suspend ActionEnv.(T) -> R
/**
* Calculate the result of goal
*/
fun result(f: suspend ActionEnv.(T) -> R) {
result = f;
}
}
class PipeAction<T : Any, R : Any>(
val inputType: KClass<T>,
val outputType: KClass<R>,
val context: CoroutineContext = EmptyCoroutineContext,
private val block: PipeBuilder<T, R>.() -> Unit
) : Action<T, R> {
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
node.checkType(inputType)
return DataNode.build(outputType) {
node.data().forEach { (name, data) ->
//merging data meta with action meta (data meta is primary)
val oldMeta = meta.builder().apply { update(data.meta) }
// creating environment from old meta and name
val env = ActionEnv(name, oldMeta)
//applying transformation from builder
val builder = PipeBuilder<T, R>(name, oldMeta).apply(block)
//getting new name
val newName = builder.name
//getting new meta
val newMeta = builder.meta.seal()
//creating a goal with custom context if provided
val goal = data.goal.pipe(context) { builder.result(env, it) }
//setting the data node
this[newName] = Data.of(outputType, goal, newMeta)
}
}
}
}
inline fun <reified T : Any, reified R : Any> DataNode<T>.pipe(
meta: Meta,
context: CoroutineContext = EmptyCoroutineContext,
noinline action: PipeBuilder<T, R>.() -> Unit
): DataNode<R> = PipeAction(T::class, R::class, context, action).invoke(this, meta)

View File

@ -1,69 +0,0 @@
package hep.dataforge.data
import hep.dataforge.meta.Laminate
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.builder
import hep.dataforge.names.Name
import hep.dataforge.names.toName
import kotlin.collections.set
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KClass
class FragmentRule<T : Any, R : Any>(val name: Name, var meta: MetaBuilder) {
lateinit var result: suspend (T) -> R
fun result(f: suspend (T) -> R) {
result = f;
}
}
class SplitBuilder<T : Any, R : Any>(val name: Name, val meta: Meta) {
internal val fragments: MutableMap<Name, FragmentRule<T, R>.() -> Unit> = HashMap()
/**
* Add new fragment building rule. If the framgent not defined, result won't be available even if it is present in the map
* @param name the name of a fragment
* @param rule the rule to transform fragment name and meta using
*/
fun fragment(name: String, rule: FragmentRule<T, R>.() -> Unit) {
fragments[name.toName()] = rule
}
}
class SplitAction<T : Any, R : Any>(
val inputType: KClass<T>,
val outputType: KClass<R>,
val context: CoroutineContext = EmptyCoroutineContext,
private val action: SplitBuilder<T, R>.() -> Unit
) : Action<T, R> {
override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> {
node.checkType(inputType)
return DataNode.build(outputType) {
node.data().forEach { (name, data) ->
val laminate = Laminate(data.meta, meta)
val split = SplitBuilder<T, R>(name, data.meta).apply(action)
// apply individual fragment rules to result
split.fragments.forEach { (fragmentName, rule) ->
val env = FragmentRule<T, R>(fragmentName, laminate.builder())
rule(env)
val goal = data.goal.pipe(context = context) { env.result(it) }
val res = Data.of(outputType, goal, env.meta)
set(env.name, res)
}
}
}
}
}

View File

@ -0,0 +1,65 @@
package space.kscience.dataforge.actions
import kotlinx.coroutines.launch
import space.kscience.dataforge.data.*
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.startsWith
import kotlin.reflect.KType
/**
* Remove all values with keys starting with [name]
*/
internal fun MutableMap<Name, *>.removeWhatStartsWith(name: Name) {
val toRemove = keys.filter { it.startsWith(name) }
toRemove.forEach(::remove)
}
/**
* An action that caches results on-demand and recalculates them on source push
*/
public abstract class AbstractAction<in T : Any, R : Any>(
public val outputType: KType,
) : Action<T, R> {
/**
* Generate initial content of the output
*/
protected abstract fun DataSetBuilder<R>.generate(
data: DataSet<T>,
meta: Meta,
)
/**
* Update part of the data set when given [updateKey] is triggered by the source
*/
protected open fun DataSourceBuilder<R>.update(
dataSet: DataSet<T>,
meta: Meta,
updateKey: Name,
) {
// By default, recalculate the whole dataset
generate(dataSet, meta)
}
@OptIn(DFInternal::class)
override fun execute(
dataSet: DataSet<T>,
meta: Meta,
): DataSet<R> = if (dataSet is DataSource) {
DataSource(outputType, dataSet){
generate(dataSet, meta)
launch {
dataSet.updates.collect { name ->
update(dataSet, meta, name)
}
}
}
} else {
DataTree<R>(outputType) {
generate(dataSet, meta)
}
}
}

View File

@ -0,0 +1,40 @@
package space.kscience.dataforge.actions
import space.kscience.dataforge.data.DataSet
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFExperimental
/**
* A simple data transformation on a data node. Actions should avoid doing actual dependency evaluation in [execute].
*/
public interface Action<in T : Any, out R : Any> {
/**
* Transform the data in the node, producing a new node. By default, it is assumed that all calculations are lazy
* so not actual computation is started at this moment.
*/
public fun execute(dataSet: DataSet<T>, meta: Meta = Meta.EMPTY): DataSet<R>
public companion object
}
/**
* Action composition. The result is terminal if one of its parts is terminal
*/
public infix fun <T : Any, I : Any, R : Any> Action<T, I>.then(action: Action<I, R>): Action<T, R> {
// TODO introduce composite action and add optimize by adding action to the list
return object : Action<T, R> {
override fun execute(
dataSet: DataSet<T>,
meta: Meta,
): DataSet<R> = action.execute(this@then.execute(dataSet, meta), meta)
}
}
@DFExperimental
public operator fun <T : Any, R : Any> Action<T, R>.invoke(
dataSet: DataSet<T>,
meta: Meta = Meta.EMPTY,
): DataSet<R> = execute(dataSet, meta)

View File

@ -0,0 +1,106 @@
package space.kscience.dataforge.actions
import space.kscience.dataforge.data.*
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.meta.seal
import space.kscience.dataforge.meta.toMutableMeta
import space.kscience.dataforge.misc.DFBuilder
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.names.Name
import kotlin.reflect.KType
import kotlin.reflect.typeOf
/**
* Action environment includes data name, data meta and action configuration meta
*/
public data class ActionEnv(
val name: Name,
val meta: Meta,
val actionMeta: Meta,
)
/**
* Action environment
*/
@DFBuilder
public class MapActionBuilder<T, R>(
public var name: Name,
public var meta: MutableMeta,
public val actionMeta: Meta,
@PublishedApi internal var outputType: KType,
) {
public lateinit var result: suspend ActionEnv.(T) -> R
/**
* Set unsafe [outputType] for the resulting data. Be sure that it is correct.
*/
public fun <R1 : R> result(outputType: KType, f: suspend ActionEnv.(T) -> R1) {
this.outputType = outputType
result = f;
}
/**
* Calculate the result of goal
*/
public inline fun <reified R1 : R> result(noinline f: suspend ActionEnv.(T) -> R1) {
outputType = typeOf<R1>()
result = f;
}
}
@PublishedApi
internal class MapAction<in T : Any, R : Any>(
outputType: KType,
private val block: MapActionBuilder<T, R>.() -> Unit,
) : AbstractAction<T, R>(outputType) {
private fun DataSetBuilder<R>.mapOne(name: Name, data: Data<T>, meta: Meta) {
// Creating a new environment for action using **old** name, old meta and task meta
val env = ActionEnv(name, data.meta, meta)
//applying transformation from builder
val builder = MapActionBuilder<T, R>(
name,
data.meta.toMutableMeta(), // using data meta
meta,
outputType
).apply(block)
//getting new name
val newName = builder.name
//getting new meta
val newMeta = builder.meta.seal()
@OptIn(DFInternal::class)
val newData = Data(builder.outputType, newMeta, dependencies = listOf(data)) {
builder.result(env, data.await())
}
//setting the data node
data(newName, newData)
}
override fun DataSetBuilder<R>.generate(data: DataSet<T>, meta: Meta) {
data.forEach { mapOne(it.name, it.data, meta) }
}
override fun DataSourceBuilder<R>.update(dataSet: DataSet<T>, meta: Meta, updateKey: Name) {
remove(updateKey)
dataSet[updateKey]?.let { mapOne(updateKey, it, meta) }
}
}
/**
* A one-to-one mapping action
*/
@DFExperimental
@Suppress("FunctionName")
public inline fun <T : Any, reified R : Any> Action.Companion.map(
noinline builder: MapActionBuilder<T, R>.() -> Unit,
): Action<T, R> = MapAction(typeOf<R>(), builder)

View File

@ -0,0 +1,117 @@
package space.kscience.dataforge.actions
import space.kscience.dataforge.data.*
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.misc.DFBuilder
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.parseAsName
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public class JoinGroup<T : Any, R : Any>(
public var name: String,
internal val set: DataSet<T>,
@PublishedApi internal var outputType: KType,
) {
public var meta: MutableMeta = MutableMeta()
public lateinit var result: suspend ActionEnv.(Map<Name, ValueWithMeta<T>>) -> R
internal fun <R1 : R> result(outputType: KType, f: suspend ActionEnv.(Map<Name, ValueWithMeta<T>>) -> R1) {
this.outputType = outputType
this.result = f;
}
public inline fun <reified R1 : R> result(noinline f: suspend ActionEnv.(Map<Name, ValueWithMeta<T>>) -> R1) {
outputType = typeOf<R1>()
this.result = f;
}
}
@DFBuilder
public class ReduceGroupBuilder<T : Any, R : Any>(
public val actionMeta: Meta,
private val outputType: KType,
) {
private val groupRules: MutableList<(DataSet<T>) -> List<JoinGroup<T, R>>> = ArrayList();
/**
* introduce grouping by meta value
*/
public fun byValue(tag: String, defaultTag: String = "@default", action: JoinGroup<T, R>.() -> Unit) {
groupRules += { node ->
GroupRule.byMetaValue(tag, defaultTag).gather(node).map {
JoinGroup<T, R>(it.key, it.value, outputType).apply(action)
}
}
}
public fun group(
groupName: String,
predicate: (Name, Meta) -> Boolean,
action: JoinGroup<T, R>.() -> Unit,
) {
groupRules += { source ->
listOf(
JoinGroup<T, R>(groupName, source.filter(predicate), outputType).apply(action)
)
}
}
/**
* Apply transformation to the whole node
*/
public fun result(resultName: String, f: suspend ActionEnv.(Map<Name, ValueWithMeta<T>>) -> R) {
groupRules += { node ->
listOf(JoinGroup<T, R>(resultName, node, outputType).apply { result(outputType, f) })
}
}
internal fun buildGroups(input: DataSet<T>): List<JoinGroup<T, R>> =
groupRules.flatMap { it.invoke(input) }
}
@PublishedApi
internal class ReduceAction<T : Any, R : Any>(
outputType: KType,
private val action: ReduceGroupBuilder<T, R>.() -> Unit,
) : AbstractAction<T, R>(outputType) {
//TODO optimize reduction. Currently, the whole action recalculates on push
override fun DataSetBuilder<R>.generate(data: DataSet<T>, meta: Meta) {
ReduceGroupBuilder<T, R>(meta, outputType).apply(action).buildGroups(data).forEach { group ->
val dataFlow: Map<Name, Data<T>> = group.set.asSequence().fold(HashMap()) { acc, value ->
acc.apply {
acc[value.name] = value.data
}
}
val groupName: String = group.name
val groupMeta = group.meta
val env = ActionEnv(groupName.parseAsName(), groupMeta, meta)
@OptIn(DFInternal::class) val res: Data<R> = dataFlow.reduceToData(
group.outputType,
meta = groupMeta
) { group.result.invoke(env, it) }
data(env.name, res)
}
}
}
/**
* A one-to-one mapping action
*/
@DFExperimental
public inline fun <reified T : Any, reified R : Any> Action.Companion.reduce(
noinline builder: ReduceGroupBuilder<T, R>.() -> Unit,
): Action<T, R> = ReduceAction(typeOf<R>(), builder)

View File

@ -0,0 +1,92 @@
package space.kscience.dataforge.actions
import space.kscience.dataforge.data.*
import space.kscience.dataforge.meta.Laminate
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.meta.toMutableMeta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.parseAsName
import kotlin.collections.set
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public class SplitBuilder<T : Any, R : Any>(public val name: Name, public val meta: Meta) {
public class FragmentRule<T : Any, R : Any>(
public val name: Name,
public var meta: MutableMeta,
@PublishedApi internal var outputType: KType,
) {
public lateinit var result: suspend (T) -> R
public inline fun <reified R1 : R> result(noinline f: suspend (T) -> R1) {
this.outputType = typeOf<R1>()
result = f;
}
}
internal val fragments: MutableMap<Name, FragmentRule<T, R>.() -> Unit> = HashMap()
/**
* Add new fragment building rule. If the framgent not defined, result won't be available even if it is present in the map
* @param name the name of a fragment
* @param rule the rule to transform fragment name and meta using
*/
public fun fragment(name: String, rule: FragmentRule<T, R>.() -> Unit) {
fragments[name.parseAsName()] = rule
}
}
/**
* Action that splits each incoming element into a number of fragments defined in builder
*/
@PublishedApi
internal class SplitAction<T : Any, R : Any>(
outputType: KType,
private val action: SplitBuilder<T, R>.() -> Unit,
) : AbstractAction<T, R>(outputType) {
private fun DataSetBuilder<R>.splitOne(name: Name, data: Data<T>, meta: Meta) {
val laminate = Laminate(data.meta, meta)
val split = SplitBuilder<T, R>(name, data.meta).apply(action)
// apply individual fragment rules to result
split.fragments.forEach { (fragmentName, rule) ->
val env = SplitBuilder.FragmentRule<T, R>(
fragmentName,
laminate.toMutableMeta(),
outputType
).apply(rule)
//data.map<R>(outputType, meta = env.meta) { env.result(it) }.named(fragmentName)
data(
fragmentName,
@Suppress("OPT_IN_USAGE") Data(outputType, meta = env.meta, dependencies = listOf(data)) {
env.result(data.await())
}
)
}
}
override fun DataSetBuilder<R>.generate(data: DataSet<T>, meta: Meta) {
data.forEach { splitOne(it.name, it.data, meta) }
}
override fun DataSourceBuilder<R>.update(dataSet: DataSet<T>, meta: Meta, updateKey: Name) {
remove(updateKey)
dataSet[updateKey]?.let { splitOne(updateKey, it, meta) }
}
}
/**
* Action that splits each incoming element into a number of fragments defined in builder
*/
@DFExperimental
public inline fun <T : Any, reified R : Any> Action.Companion.split(
noinline builder: SplitBuilder<T, R>.() -> Unit,
): Action<T, R> = SplitAction(typeOf<R>(), builder)

View File

@ -0,0 +1,57 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import space.kscience.dataforge.misc.DFExperimental
import kotlin.coroutines.CoroutineContext
/**
* A monitor of goal state that could be accessed only form inside the goal
*/
@DFExperimental
public class CoroutineMonitor : CoroutineContext.Element {
override val key: CoroutineContext.Key<*> get() = CoroutineMonitor
public var totalWork: Double = 1.0
public var workDone: Double = 0.0
public var status: String = ""
/**
* Mark the goal as started
*/
public fun start() {
}
/**
* Mark the goal as completed
*/
public fun finish() {
workDone = totalWork
}
public companion object : CoroutineContext.Key<CoroutineMonitor>
}
public class Dependencies(public val values: Collection<Job>) : CoroutineContext.Element {
override val key: CoroutineContext.Key<*> get() = Dependencies
public companion object : CoroutineContext.Key<Dependencies>
}
@DFExperimental
public val CoroutineContext.monitor: CoroutineMonitor? get() = this[CoroutineMonitor]
@DFExperimental
public val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.monitor
public val Job.dependencies: Collection<Job> get() = this[Dependencies]?.values ?: emptyList()
@DFExperimental
public val Job.totalWork: Double get() = dependencies.sumOf { totalWork } + (monitor?.totalWork ?: 0.0)
@DFExperimental
public val Job.workDone: Double get() = dependencies.sumOf { workDone } + (monitor?.workDone ?: 0.0)
@DFExperimental
public val Job.status: String get() = monitor?.status ?: ""
@DFExperimental
public val Job.progress: Double get() = workDone / totalWork

View File

@ -0,0 +1,107 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.*
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MetaRepr
import space.kscience.dataforge.meta.isEmpty
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.misc.DfId
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KType
import kotlin.reflect.typeOf
/**
* A data element characterized by its meta
*/
@DfId(Data.TYPE)
public interface Data<out T> : Goal<T>, MetaRepr {
/**
* Type marker for the data. The type is known before the calculation takes place so it could be checked.
*/
public val type: KType
/**
* Meta for the data
*/
public val meta: Meta
override fun toMeta(): Meta = Meta {
"type" put (type.toString())
if (!meta.isEmpty()) {
"meta" put meta
}
}
public companion object {
public const val TYPE: String = "data"
/**
* The type that can't have any subtypes
*/
internal val TYPE_OF_NOTHING: KType = typeOf<Unit>()
public inline fun <reified T : Any> static(
value: T,
meta: Meta = Meta.EMPTY,
): Data<T> = StaticData(typeOf<T>(), value, meta)
/**
* An empty data containing only meta
*/
@OptIn(DelicateCoroutinesApi::class)
public fun empty(meta: Meta): Data<Nothing> = object : Data<Nothing> {
override val type: KType = TYPE_OF_NOTHING
override val meta: Meta = meta
override val dependencies: Collection<Goal<*>> = emptyList()
override val deferred: Deferred<Nothing>
get() = GlobalScope.async(start = CoroutineStart.LAZY) {
error("The Data is empty and could not be computed")
}
override fun async(coroutineScope: CoroutineScope): Deferred<Nothing> = deferred
override fun reset() {}
}
}
}
/**
* A lazily computed variant of [Data] based on [LazyGoal]
* One must ensure that proper [type] is used so this method should not be used
*/
private class LazyData<T : Any>(
override val type: KType,
override val meta: Meta = Meta.EMPTY,
additionalContext: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection<Goal<*>> = emptyList(),
block: suspend () -> T,
) : Data<T>, LazyGoal<T>(additionalContext, dependencies, block)
public class StaticData<T : Any>(
override val type: KType,
value: T,
override val meta: Meta = Meta.EMPTY,
) : Data<T>, StaticGoal<T>(value)
@Suppress("FunctionName")
public inline fun <reified T : Any> Data(value: T, meta: Meta = Meta.EMPTY): StaticData<T> =
StaticData(typeOf<T>(), value, meta)
@Suppress("FunctionName")
@DFInternal
public fun <T : Any> Data(
type: KType,
meta: Meta = Meta.EMPTY,
context: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection<Goal<*>> = emptyList(),
block: suspend () -> T,
): Data<T> = LazyData(type, meta, context, dependencies, block)
@OptIn(DFInternal::class)
@Suppress("FunctionName")
public inline fun <reified T : Any> Data(
meta: Meta = Meta.EMPTY,
context: CoroutineContext = EmptyCoroutineContext,
dependencies: Collection<Goal<*>> = emptyList(),
noinline block: suspend () -> T,
): Data<T> = Data(typeOf<T>(), meta, context, dependencies, block)

View File

@ -0,0 +1,124 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.mapNotNull
import space.kscience.dataforge.data.Data.Companion.TYPE_OF_NOTHING
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.endsWith
import space.kscience.dataforge.names.parseAsName
import kotlin.reflect.KType
public interface DataSet<out T : Any> {
/**
* The minimal common ancestor to all data in the node
*/
public val dataType: KType
/**
* Meta-data associated with this node. If no meta is provided, returns [Meta.EMPTY].
*/
public val meta: Meta
/**
* Traverse this [DataSet] returning named data instances. The order is not guaranteed.
*/
public operator fun iterator(): Iterator<NamedData<T>>
/**
* Get data with given name.
*/
public operator fun get(name: Name): Data<T>?
public companion object {
public val META_KEY: Name = "@meta".asName()
/**
* An empty [DataSet] that suits all types
*/
public val EMPTY: DataSet<Nothing> = object : DataSet<Nothing> {
override val dataType: KType = TYPE_OF_NOTHING
override val meta: Meta get() = Meta.EMPTY
override fun iterator(): Iterator<NamedData<Nothing>> = emptySequence<NamedData<Nothing>>().iterator()
override fun get(name: Name): Data<Nothing>? = null
}
}
}
public fun <T : Any> DataSet<T>.asSequence(): Sequence<NamedData<T>> = object : Sequence<NamedData<T>> {
override fun iterator(): Iterator<NamedData<T>> = this@asSequence.iterator()
}
/**
* Return a single [Data] in this [DataSet]. Throw error if it is not single.
*/
public fun <T : Any> DataSet<T>.single(): NamedData<T> = asSequence().single()
public fun <T : Any> DataSet<T>.asIterable(): Iterable<NamedData<T>> = object : Iterable<NamedData<T>> {
override fun iterator(): Iterator<NamedData<T>> = this@asIterable.iterator()
}
public operator fun <T : Any> DataSet<T>.get(name: String): Data<T>? = get(name.parseAsName())
/**
* A [DataSet] with propagated updates.
*/
public interface DataSource<out T : Any> : DataSet<T>, CoroutineScope {
/**
* A flow of updated item names. Updates are propagated in a form of [Flow] of names of updated nodes.
* Those can include new data items and replacement of existing ones. The replaced items could update existing data content
* and replace it completely, so they should be pulled again.
*
*/
public val updates: Flow<Name>
/**
* Stop generating updates from this [DataSource]
*/
public fun close() {
coroutineContext[Job]?.cancel()
}
}
public val <T : Any> DataSet<T>.updates: Flow<Name> get() = if (this is DataSource) updates else emptyFlow()
//
///**
// * Flow all data nodes with names starting with [branchName]
// */
//public fun <T : Any> DataSet<T>.children(branchName: Name): Sequence<NamedData<T>> =
// this@children.asSequence().filter {
// it.name.startsWith(branchName)
// }
/**
* Start computation for all goals in data node and return a job for the whole node
*/
public fun <T : Any> DataSet<T>.startAll(coroutineScope: CoroutineScope): Job = coroutineScope.launch {
asIterable().map {
it.launch(this@launch)
}.joinAll()
}
public suspend fun <T : Any> DataSet<T>.computeAndJoinAll(): Unit = coroutineScope { startAll(this).join() }
public fun DataSet<*>.toMeta(): Meta = Meta {
forEach {
if (it.name.endsWith(DataSet.META_KEY)) {
set(it.name, it.meta)
} else {
it.name put {
"type" put it.type.toString()
"meta" put it.meta
}
}
}
}
public val <T : Any> DataSet<T>.updatesWithData: Flow<NamedData<T>> get() = updates.mapNotNull { get(it)?.named(it) }

View File

@ -0,0 +1,165 @@
package space.kscience.dataforge.data
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.isEmpty
import space.kscience.dataforge.names.plus
import kotlin.reflect.KType
public interface DataSetBuilder<in T : Any> {
public val dataType: KType
/**
* Remove all data items starting with [name]
*/
public fun remove(name: Name)
public fun data(name: Name, data: Data<T>?)
/**
* Set a current state of given [dataSet] into a branch [name]. Does not propagate updates
*/
public fun node(name: Name, dataSet: DataSet<T>) {
//remove previous items
if (name != Name.EMPTY) {
remove(name)
}
//Set new items
dataSet.forEach {
data(name + it.name, it.data)
}
}
/**
* Set meta for the given node
*/
public fun meta(name: Name, meta: Meta)
}
/**
* Define meta in this [DataSet]
*/
public fun <T : Any> DataSetBuilder<T>.meta(value: Meta): Unit = meta(Name.EMPTY, value)
/**
* Define meta in this [DataSet]
*/
public fun <T : Any> DataSetBuilder<T>.meta(mutableMeta: MutableMeta.() -> Unit): Unit = meta(Meta(mutableMeta))
@PublishedApi
internal class SubSetBuilder<in T : Any>(
private val parent: DataSetBuilder<T>,
private val branch: Name,
) : DataSetBuilder<T> {
override val dataType: KType get() = parent.dataType
override fun remove(name: Name) {
parent.remove(branch + name)
}
override fun data(name: Name, data: Data<T>?) {
parent.data(branch + name, data)
}
override fun node(name: Name, dataSet: DataSet<T>) {
parent.node(branch + name, dataSet)
}
override fun meta(name: Name, meta: Meta) {
parent.meta(branch + name, meta)
}
}
public inline fun <T : Any> DataSetBuilder<T>.node(
name: Name,
crossinline block: DataSetBuilder<T>.() -> Unit,
) {
if (name.isEmpty()) block() else SubSetBuilder(this, name).block()
}
public fun <T : Any> DataSetBuilder<T>.data(name: String, value: Data<T>) {
data(Name.parse(name), value)
}
public fun <T : Any> DataSetBuilder<T>.node(name: String, set: DataSet<T>) {
node(Name.parse(name), set)
}
public inline fun <T : Any> DataSetBuilder<T>.node(
name: String,
crossinline block: DataSetBuilder<T>.() -> Unit,
): Unit = node(Name.parse(name), block)
public fun <T : Any> DataSetBuilder<T>.set(value: NamedData<T>) {
data(value.name, value.data)
}
/**
* Produce lazy [Data] and emit it into the [DataSetBuilder]
*/
public inline fun <reified T : Any> DataSetBuilder<T>.produce(
name: String,
meta: Meta = Meta.EMPTY,
noinline producer: suspend () -> T,
) {
val data = Data(meta, block = producer)
data(name, data)
}
public inline fun <reified T : Any> DataSetBuilder<T>.produce(
name: Name,
meta: Meta = Meta.EMPTY,
noinline producer: suspend () -> T,
) {
val data = Data(meta, block = producer)
data(name, data)
}
/**
* Emit a static data with the fixed value
*/
public inline fun <reified T : Any> DataSetBuilder<T>.static(
name: String,
data: T,
meta: Meta = Meta.EMPTY,
): Unit = data(name, Data.static(data, meta))
public inline fun <reified T : Any> DataSetBuilder<T>.static(
name: Name,
data: T,
meta: Meta = Meta.EMPTY,
): Unit = data(name, Data.static(data, meta))
public inline fun <reified T : Any> DataSetBuilder<T>.static(
name: String,
data: T,
mutableMeta: MutableMeta.() -> Unit,
): Unit = data(Name.parse(name), Data.static(data, Meta(mutableMeta)))
/**
* Update data with given node data and meta with node meta.
*/
@DFExperimental
public fun <T : Any> DataSetBuilder<T>.populateFrom(tree: DataSet<T>): Unit {
tree.forEach {
//TODO check if the place is occupied
data(it.name, it.data)
}
}
//public fun <T : Any> DataSetBuilder<T>.populateFrom(flow: Flow<NamedData<T>>) {
// flow.collect {
// data(it.name, it.data)
// }
//}
public fun <T : Any> DataSetBuilder<T>.populateFrom(sequence: Sequence<NamedData<T>>) {
sequence.forEach {
data(it.name, it.data)
}
}

View File

@ -0,0 +1,119 @@
package space.kscience.dataforge.data
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.misc.DfId
import space.kscience.dataforge.names.*
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public sealed class DataTreeItem<out T : Any> {
public abstract val meta: Meta
public class Node<out T : Any>(public val tree: DataTree<T>) : DataTreeItem<T>() {
override val meta: Meta get() = tree.meta
}
public class Leaf<out T : Any>(public val data: Data<T>) : DataTreeItem<T>() {
override val meta: Meta get() = data.meta
}
}
public val <T : Any> DataTreeItem<T>.type: KType
get() = when (this) {
is DataTreeItem.Node -> tree.dataType
is DataTreeItem.Leaf -> data.type
}
/**
* A tree-like [DataSet] grouped into the node. All data inside the node must inherit its type
*/
@DfId(DataTree.TYPE)
public interface DataTree<out T : Any> : DataSet<T> {
/**
* Top-level children items of this [DataTree]
*/
public val items: Map<NameToken, DataTreeItem<T>>
override val meta: Meta get() = items[META_ITEM_NAME_TOKEN]?.meta ?: Meta.EMPTY
override fun iterator(): Iterator<NamedData<T>> = iterator {
items.forEach { (token, childItem: DataTreeItem<T>) ->
if (!token.body.startsWith("@")) {
when (childItem) {
is DataTreeItem.Leaf -> yield(childItem.data.named(token.asName()))
is DataTreeItem.Node -> yieldAll(childItem.tree.asSequence().map { it.named(token + it.name) })
}
}
}
}
override fun get(name: Name): Data<T>? = when (name.length) {
0 -> null
1 -> items[name.firstOrNull()!!].data
else -> items[name.firstOrNull()!!].tree?.get(name.cutFirst())
}
public companion object {
public const val TYPE: String = "dataTree"
/**
* A name token used to designate tree node meta
*/
public val META_ITEM_NAME_TOKEN: NameToken = NameToken("@meta")
@DFInternal
public fun <T : Any> emptyWithType(type: KType, meta: Meta = Meta.EMPTY): DataTree<T> = object : DataTree<T> {
override val items: Map<NameToken, DataTreeItem<T>> get() = emptyMap()
override val dataType: KType get() = type
override val meta: Meta get() = meta
}
@OptIn(DFInternal::class)
public inline fun <reified T : Any> empty(meta: Meta = Meta.EMPTY): DataTree<T> =
emptyWithType<T>(typeOf<T>(), meta)
}
}
public fun <T : Any> DataTree<T>.listChildren(prefix: Name): List<Name> =
getItem(prefix).tree?.items?.keys?.map { prefix + it } ?: emptyList()
/**
* Get a [DataTreeItem] with given [name] or null if the item does not exist
*/
public tailrec fun <T : Any> DataTree<T>.getItem(name: Name): DataTreeItem<T>? = when (name.length) {
0 -> DataTreeItem.Node(this)
1 -> items[name.firstOrNull()]
else -> items[name.firstOrNull()!!].tree?.getItem(name.cutFirst())
}
public val <T : Any> DataTreeItem<T>?.tree: DataTree<T>? get() = (this as? DataTreeItem.Node<T>)?.tree
public val <T : Any> DataTreeItem<T>?.data: Data<T>? get() = (this as? DataTreeItem.Leaf<T>)?.data
/**
* A [Sequence] of all children including nodes
*/
public fun <T : Any> DataTree<T>.traverseItems(): Sequence<Pair<Name, DataTreeItem<T>>> = sequence {
items.forEach { (head, item) ->
yield(head.asName() to item)
if (item is DataTreeItem.Node) {
val subSequence = item.tree.traverseItems()
.map { (name, data) -> (head.asName() + name) to data }
yieldAll(subSequence)
}
}
}
/**
* Get a branch of this [DataTree] with a given [branchName].
* The difference from similar method for [DataSet] is that internal logic is more simple and the return value is a [DataTree]
*/
@OptIn(DFInternal::class)
public fun <T : Any> DataTree<T>.branch(branchName: Name): DataTree<T> =
getItem(branchName)?.tree ?: DataTree.emptyWithType(dataType)
public fun <T : Any> DataTree<T>.branch(branchName: String): DataTree<T> = branch(branchName.parseAsName())

View File

@ -0,0 +1,127 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.misc.ThreadSafe
import space.kscience.dataforge.names.*
import kotlin.collections.set
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public interface DataSourceBuilder<T : Any> : DataSetBuilder<T>, DataSource<T> {
override val updates: MutableSharedFlow<Name>
}
/**
* A mutable [DataTree] that propagates updates
*/
public class DataTreeBuilder<T : Any>(
override val dataType: KType,
coroutineContext: CoroutineContext,
) : DataTree<T>, DataSourceBuilder<T> {
override val coroutineContext: CoroutineContext =
coroutineContext + Job(coroutineContext[Job]) + GoalExecutionRestriction()
private val treeItems = HashMap<NameToken, DataTreeItem<T>>()
override val items: Map<NameToken, DataTreeItem<T>>
get() = treeItems.filter { !it.key.body.startsWith("@") }
override val updates: MutableSharedFlow<Name> = MutableSharedFlow<Name>()
@ThreadSafe
private fun remove(token: NameToken) {
if (treeItems.remove(token) != null) {
launch {
updates.emit(token.asName())
}
}
}
override fun remove(name: Name) {
if (name.isEmpty()) error("Can't remove the root node")
(getItem(name.cutLast()).tree as? DataTreeBuilder)?.remove(name.lastOrNull()!!)
}
@ThreadSafe
private fun set(token: NameToken, data: Data<T>) {
treeItems[token] = DataTreeItem.Leaf(data)
}
@ThreadSafe
private fun set(token: NameToken, node: DataTree<T>) {
treeItems[token] = DataTreeItem.Node(node)
}
private fun getOrCreateNode(token: NameToken): DataTreeBuilder<T> =
(treeItems[token] as? DataTreeItem.Node<T>)?.tree as? DataTreeBuilder<T>
?: DataTreeBuilder<T>(dataType, coroutineContext).also { set(token, it) }
private fun getOrCreateNode(name: Name): DataTreeBuilder<T> = when (name.length) {
0 -> this
1 -> getOrCreateNode(name.firstOrNull()!!)
else -> getOrCreateNode(name.firstOrNull()!!).getOrCreateNode(name.cutFirst())
}
override fun data(name: Name, data: Data<T>?) {
if (data == null) {
remove(name)
} else {
when (name.length) {
0 -> error("Can't add data with empty name")
1 -> set(name.firstOrNull()!!, data)
2 -> getOrCreateNode(name.cutLast()).set(name.lastOrNull()!!, data)
}
}
launch {
updates.emit(name)
}
}
override fun meta(name: Name, meta: Meta) {
val item = getItem(name)
if (item is DataTreeItem.Leaf) error("TODO: Can't change meta of existing leaf item.")
data(name + DataTree.META_ITEM_NAME_TOKEN, Data.empty(meta))
}
}
/**
* Create a dynamic [DataSource]. Initial data is placed synchronously.
*/
@DFInternal
@Suppress("FunctionName")
public fun <T : Any> DataSource(
type: KType,
parent: CoroutineScope,
block: DataSourceBuilder<T>.() -> Unit,
): DataTreeBuilder<T> = DataTreeBuilder<T>(type, parent.coroutineContext).apply(block)
@Suppress("OPT_IN_USAGE", "FunctionName")
public inline fun <reified T : Any> DataSource(
parent: CoroutineScope,
crossinline block: DataSourceBuilder<T>.() -> Unit,
): DataTreeBuilder<T> = DataSource(typeOf<T>(), parent) { block() }
@Suppress("FunctionName")
public suspend inline fun <reified T : Any> DataSource(
crossinline block: DataSourceBuilder<T>.() -> Unit = {},
): DataTreeBuilder<T> = DataTreeBuilder<T>(typeOf<T>(), coroutineContext).apply { block() }
public inline fun <reified T : Any> DataSourceBuilder<T>.emit(
name: Name,
parent: CoroutineScope,
noinline block: DataSourceBuilder<T>.() -> Unit,
): Unit = node(name, DataSource(parent, block))
public inline fun <reified T : Any> DataSourceBuilder<T>.emit(
name: String,
parent: CoroutineScope,
noinline block: DataSourceBuilder<T>.() -> Unit,
): Unit = node(Name.parse(name), DataSource(parent, block))

View File

@ -0,0 +1,112 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.*
import space.kscience.dataforge.misc.DFExperimental
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* Lazy computation result with its dependencies to allowing to stat computing dependencies ahead of time
*/
public interface Goal<out T> {
public val dependencies: Collection<Goal<*>>
/**
* Returns current running coroutine if the goal is started. Null if the computation is not started.
*/
public val deferred: Deferred<T>?
/**
* Get ongoing computation or start a new one.
* Does not guarantee thread safety. In case of multi-thread access, could create orphan computations.
*
* If the computation is already running, the scope is not used.
*/
public fun async(coroutineScope: CoroutineScope): Deferred<T>
/**
* Reset the computation
*/
public fun reset()
public companion object
}
public fun Goal<*>.launch(coroutineScope: CoroutineScope): Job = async(coroutineScope)
public suspend fun <T> Goal<T>.await(): T = coroutineScope { async(this).await() }
public val Goal<*>.isComplete: Boolean get() = deferred?.isCompleted ?: false
public open class StaticGoal<T>(public val value: T) : Goal<T> {
override val dependencies: Collection<Goal<*>> get() = emptyList()
override val deferred: Deferred<T> = CompletableDeferred(value)
override fun async(coroutineScope: CoroutineScope): Deferred<T> = deferred
override fun reset() {
//doNothing
}
}
/**
* @param coroutineContext additional context information
*/
public open class LazyGoal<T>(
private val coroutineContext: CoroutineContext = EmptyCoroutineContext,
override val dependencies: Collection<Goal<*>> = emptyList(),
public val block: suspend () -> T,
) : Goal<T> {
final override var deferred: Deferred<T>? = null
private set
/**
* Get ongoing computation or start a new one.
* Does not guarantee thread safety. In case of multi-thread access, could create orphan computations.
* If [GoalExecutionRestriction] is present in the [coroutineScope] context, the call could produce a error a warning
* depending on the settings.
*/
@OptIn(DFExperimental::class)
override fun async(coroutineScope: CoroutineScope): Deferred<T> {
val log = coroutineScope.coroutineContext[GoalLogger]
// Check if context restricts goal computation
coroutineScope.coroutineContext[GoalExecutionRestriction]?.let { restriction ->
when (restriction.policy) {
GoalExecutionRestrictionPolicy.WARNING -> log?.emit(GoalLogger.WARNING_TAG) { "Goal eager execution is prohibited by the coroutine scope policy" }
GoalExecutionRestrictionPolicy.ERROR -> error("Goal eager execution is prohibited by the coroutine scope policy")
else -> {
/*do nothing*/
}
}
}
log?.emit { "Starting dependencies computation for ${this@LazyGoal}" }
val startedDependencies = this.dependencies.map { goal ->
goal.run { async(coroutineScope) }
}
return deferred ?: coroutineScope.async(
coroutineContext
+ CoroutineMonitor()
+ Dependencies(startedDependencies)
+ GoalExecutionRestriction(GoalExecutionRestrictionPolicy.NONE) // Remove restrictions on goal execution
) {
//cancel execution if error encountered in one of dependencies
startedDependencies.forEach { deferred ->
deferred.invokeOnCompletion { error ->
if (error != null) this.cancel(CancellationException("Dependency $deferred failed with error: ${error.message}"))
}
}
coroutineContext[GoalLogger]?.emit { "Starting computation of ${this@LazyGoal}" }
block()
}.also { deferred = it }
}
/**
* Reset the computation
*/
override fun reset() {
deferred?.cancel()
deferred = null
}
}

View File

@ -0,0 +1,31 @@
package space.kscience.dataforge.data
import kotlin.coroutines.CoroutineContext
public enum class GoalExecutionRestrictionPolicy {
/**
* Allow eager execution
*/
NONE,
/**
* Give warning on eager execution
*/
WARNING,
/**
* Throw error on eager execution
*/
ERROR
}
/**
* A special coroutine context key that allows or disallows goal execution during configuration time (eager execution).
*/
public class GoalExecutionRestriction(
public val policy: GoalExecutionRestrictionPolicy = GoalExecutionRestrictionPolicy.ERROR,
) : CoroutineContext.Element {
override val key: CoroutineContext.Key<*> get() = Companion
public companion object : CoroutineContext.Key<GoalExecutionRestriction>
}

View File

@ -0,0 +1,16 @@
package space.kscience.dataforge.data
import kotlin.coroutines.CoroutineContext
/**
* Coroutine context element that provides logging capabilities
*/
public interface GoalLogger : CoroutineContext.Element {
override val key: CoroutineContext.Key<*> get() = GoalLogger
public fun emit(vararg tags: String, message: suspend () -> String)
public companion object : CoroutineContext.Key<GoalLogger>{
public const val WARNING_TAG: String = "WARNING"
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2015 Alexander Nozik.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package space.kscience.dataforge.data
import kotlinx.coroutines.launch
import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.string
import space.kscience.dataforge.misc.DFInternal
public interface GroupRule {
public fun <T : Any> gather(set: DataSet<T>): Map<String, DataSet<T>>
public companion object {
/**
* Create grouping rule that creates groups for different values of value
* field with name [key]
*
* @param key
* @param defaultTagValue
* @return
*/
@OptIn(DFInternal::class)
public fun byMetaValue(
key: String,
defaultTagValue: String,
): GroupRule = object : GroupRule {
override fun <T : Any> gather(
set: DataSet<T>,
): Map<String, DataSet<T>> {
val map = HashMap<String, DataSet<T>>()
if (set is DataSource) {
set.forEach { data ->
val tagValue: String = data.meta[key]?.string ?: defaultTagValue
(map.getOrPut(tagValue) { DataTreeBuilder(set.dataType, set.coroutineContext) } as DataTreeBuilder<T>)
.data(data.name, data.data)
set.launch {
set.updates.collect { name ->
val dataUpdate = set[name]
val updateTagValue = dataUpdate?.meta?.get(key)?.string ?: defaultTagValue
map.getOrPut(updateTagValue) {
DataSource(set.dataType, this) {
data(name, dataUpdate)
}
}
}
}
}
} else {
set.forEach { data ->
val tagValue: String = data.meta[key]?.string ?: defaultTagValue
(map.getOrPut(tagValue) { StaticDataTree(set.dataType) } as StaticDataTree<T>)
.data(data.name, data.data)
}
}
return map
}
}
}
}

View File

@ -0,0 +1,35 @@
package space.kscience.dataforge.data
import space.kscience.dataforge.meta.isEmpty
import space.kscience.dataforge.misc.Named
import space.kscience.dataforge.names.Name
public interface NamedData<out T : Any> : Named, Data<T> {
override val name: Name
public val data: Data<T>
}
public operator fun NamedData<*>.component1(): Name = name
public operator fun <T: Any> NamedData<T>.component2(): Data<T> = data
private class NamedDataImpl<out T : Any>(
override val name: Name,
override val data: Data<T>,
) : Data<T> by data, NamedData<T> {
override fun toString(): String = buildString {
append("NamedData(name=\"$name\"")
if (data is StaticData) {
append(", value=${data.value}")
}
if (!data.meta.isEmpty()) {
append(", meta=${data.meta}")
}
append(")")
}
}
public fun <T : Any> Data<T>.named(name: Name): NamedData<T> = if (this is NamedData) {
NamedDataImpl(name, this.data)
} else {
NamedDataImpl(name, this)
}

View File

@ -0,0 +1,82 @@
package space.kscience.dataforge.data
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.*
import kotlin.reflect.KType
import kotlin.reflect.typeOf
@PublishedApi
internal class StaticDataTree<T : Any>(
override val dataType: KType,
) : DataSetBuilder<T>, DataTree<T> {
private val _items: MutableMap<NameToken, DataTreeItem<T>> = HashMap()
override val items: Map<NameToken, DataTreeItem<T>>
get() = _items.filter { !it.key.body.startsWith("@") }
override fun remove(name: Name) {
when (name.length) {
0 -> error("Can't remove root tree node")
1 -> _items.remove(name.firstOrNull()!!)
else -> (_items[name.firstOrNull()!!].tree as? StaticDataTree<T>)?.remove(name.cutFirst())
}
}
private fun getOrCreateNode(name: Name): StaticDataTree<T> = when (name.length) {
0 -> this
1 -> {
val itemName = name.firstOrNull()!!
(_items[itemName].tree as? StaticDataTree<T>) ?: StaticDataTree<T>(dataType).also {
_items[itemName] = DataTreeItem.Node(it)
}
}
else -> getOrCreateNode(name.cutLast()).getOrCreateNode(name.lastOrNull()!!.asName())
}
private fun set(name: Name, item: DataTreeItem<T>?) {
if (name.isEmpty()) error("Can't set top level tree node")
if (item == null) {
remove(name)
} else {
getOrCreateNode(name.cutLast())._items[name.lastOrNull()!!] = item
}
}
override fun data(name: Name, data: Data<T>?) {
set(name, data?.let { DataTreeItem.Leaf(it) })
}
override fun node(name: Name, dataSet: DataSet<T>) {
if (dataSet is StaticDataTree) {
set(name, DataTreeItem.Node(dataSet))
} else {
dataSet.forEach {
data(name + it.name, it.data)
}
}
}
override fun meta(name: Name, meta: Meta) {
val item = getItem(name)
if (item is DataTreeItem.Leaf) TODO("Can't change meta of existing leaf item.")
data(name + DataTree.META_ITEM_NAME_TOKEN, Data.empty(meta))
}
}
@Suppress("FunctionName")
public inline fun <T : Any> DataTree(
dataType: KType,
block: DataSetBuilder<T>.() -> Unit,
): DataTree<T> = StaticDataTree<T>(dataType).apply { block() }
@Suppress("FunctionName")
public inline fun <reified T : Any> DataTree(
noinline block: DataSetBuilder<T>.() -> Unit,
): DataTree<T> = DataTree(typeOf<T>(), block)
@OptIn(DFExperimental::class)
public fun <T : Any> DataSet<T>.seal(): DataTree<T> = DataTree(dataType) {
populateFrom(this@seal)
}

View File

@ -0,0 +1,105 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.*
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KType
/**
* A stateless filtered [DataSet]
*/
public fun <T : Any> DataSet<T>.filter(
predicate: (Name, Meta) -> Boolean,
): DataSource<T> = object : DataSource<T> {
override val dataType: KType get() = this@filter.dataType
override val coroutineContext: CoroutineContext
get() = (this@filter as? DataSource)?.coroutineContext ?: EmptyCoroutineContext
override val meta: Meta get() = this@filter.meta
override fun iterator(): Iterator<NamedData<T>> = iterator {
for (d in this@filter) {
if (predicate(d.name, d.meta)) {
yield(d)
}
}
}
override fun get(name: Name): Data<T>? = this@filter.get(name)?.takeIf {
predicate(name, it.meta)
}
override val updates: Flow<Name> = this@filter.updates.filter flowFilter@{ name ->
val theData = this@filter[name] ?: return@flowFilter false
predicate(name, theData.meta)
}
}
/**
* Generate a wrapper data set with a given name prefix appended to all names
*/
public fun <T : Any> DataSet<T>.withNamePrefix(prefix: Name): DataSet<T> = if (prefix.isEmpty()) {
this
} else object : DataSource<T> {
override val dataType: KType get() = this@withNamePrefix.dataType
override val coroutineContext: CoroutineContext
get() = (this@withNamePrefix as? DataSource)?.coroutineContext ?: EmptyCoroutineContext
override val meta: Meta get() = this@withNamePrefix.meta
override fun iterator(): Iterator<NamedData<T>> = iterator {
for (d in this@withNamePrefix) {
yield(d.data.named(prefix + d.name))
}
}
override fun get(name: Name): Data<T>? =
name.removeFirstOrNull(name)?.let { this@withNamePrefix.get(it) }
override val updates: Flow<Name> get() = this@withNamePrefix.updates.map { prefix + it }
}
/**
* Get a subset of data starting with a given [branchName]
*/
public fun <T : Any> DataSet<T>.branch(branchName: Name): DataSet<T> = if (branchName.isEmpty()) {
this
} else object : DataSource<T> {
override val dataType: KType get() = this@branch.dataType
override val coroutineContext: CoroutineContext
get() = (this@branch as? DataSource)?.coroutineContext ?: EmptyCoroutineContext
override val meta: Meta get() = this@branch.meta
override fun iterator(): Iterator<NamedData<T>> = iterator {
for (d in this@branch) {
d.name.removeFirstOrNull(branchName)?.let { name ->
yield(d.data.named(name))
}
}
}
override fun get(name: Name): Data<T>? = this@branch.get(branchName + name)
override val updates: Flow<Name> get() = this@branch.updates.mapNotNull { it.removeFirstOrNull(branchName) }
}
public fun <T : Any> DataSet<T>.branch(branchName: String): DataSet<T> = this@branch.branch(branchName.parseAsName())
@DFExperimental
public suspend fun <T : Any> DataSet<T>.rootData(): Data<T>? = get(Name.EMPTY)

View File

@ -0,0 +1,221 @@
package space.kscience.dataforge.data
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.meta.seal
import space.kscience.dataforge.meta.toMutableMeta
import space.kscience.dataforge.misc.DFInternal
import space.kscience.dataforge.names.Name
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public data class ValueWithMeta<T>(val meta: Meta, val value: T)
public suspend fun <T : Any> Data<T>.awaitWithMeta(): ValueWithMeta<T> = ValueWithMeta(meta, await())
public data class NamedValueWithMeta<T>(val name: Name, val meta: Meta, val value: T)
public suspend fun <T : Any> NamedData<T>.awaitWithMeta(): NamedValueWithMeta<T> =
NamedValueWithMeta(name, meta, await())
/**
* Lazily transform this data to another data. By convention [block] should not use external data (be pure).
* @param coroutineContext additional [CoroutineContext] elements used for data computation.
* @param meta for the resulting data. By default equals input data.
* @param block the transformation itself
*/
public inline fun <T : Any, reified R : Any> Data<T>.map(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = this.meta,
crossinline block: suspend (T) -> R,
): Data<R> = Data(meta, coroutineContext, listOf(this)) {
block(await())
}
/**
* Combine this data with the other data using [block]. See [Data::map] for other details
*/
public inline fun <T1 : Any, T2 : Any, reified R : Any> Data<T1>.combine(
other: Data<T2>,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = this.meta,
crossinline block: suspend (left: T1, right: T2) -> R,
): Data<R> = Data(meta, coroutineContext, listOf(this, other)) {
block(await(), other.await())
}
//data collection operations
/**
* Lazily reduce a collection of [Data] to a single data.
*/
public inline fun <T : Any, reified R : Any> Collection<Data<T>>.reduceToData(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline block: suspend (List<ValueWithMeta<T>>) -> R,
): Data<R> = Data(
meta,
coroutineContext,
this
) {
block(map { it.awaitWithMeta() })
}
@DFInternal
public fun <K, T : Any, R : Any> Map<K, Data<T>>.reduceToData(
outputType: KType,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
block: suspend (Map<K, ValueWithMeta<T>>) -> R,
): Data<R> = Data(
outputType,
meta,
coroutineContext,
this.values
) {
block(mapValues { it.value.awaitWithMeta() })
}
/**
* Lazily reduce a [Map] of [Data] with any static key.
* @param K type of the map key
* @param T type of the input goal
* @param R type of the result goal
*/
public inline fun <K, T : Any, reified R : Any> Map<K, Data<T>>.reduceToData(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline block: suspend (Map<K, ValueWithMeta<T>>) -> R,
): Data<R> = Data(
meta,
coroutineContext,
this.values
) {
block(mapValues { it.value.awaitWithMeta() })
}
//Iterable operations
@DFInternal
public inline fun <T : Any, R : Any> Iterable<Data<T>>.reduceToData(
outputType: KType,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline transformation: suspend (Collection<ValueWithMeta<T>>) -> R,
): Data<R> = Data(
outputType,
meta,
coroutineContext,
toList()
) {
transformation(map { it.awaitWithMeta() })
}
@OptIn(DFInternal::class)
public inline fun <T : Any, reified R : Any> Iterable<Data<T>>.reduceToData(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline transformation: suspend (Collection<ValueWithMeta<T>>) -> R,
): Data<R> = reduceToData(typeOf<R>(), coroutineContext, meta) {
transformation(it)
}
public inline fun <T : Any, reified R : Any> Iterable<Data<T>>.foldToData(
initial: R,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline block: suspend (result: R, data: ValueWithMeta<T>) -> R,
): Data<R> = reduceToData(
coroutineContext, meta
) {
it.fold(initial) { acc, t -> block(acc, t) }
}
/**
* Transform an [Iterable] of [NamedData] to a single [Data].
*/
@DFInternal
public inline fun <T : Any, R : Any> Iterable<NamedData<T>>.reduceNamedToData(
outputType: KType,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline transformation: suspend (Collection<NamedValueWithMeta<T>>) -> R,
): Data<R> = Data(
outputType,
meta,
coroutineContext,
toList()
) {
transformation(map { it.awaitWithMeta() })
}
@OptIn(DFInternal::class)
public inline fun <T : Any, reified R : Any> Iterable<NamedData<T>>.reduceNamedToData(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline transformation: suspend (Collection<NamedValueWithMeta<T>>) -> R,
): Data<R> = reduceNamedToData(typeOf<R>(), coroutineContext, meta) {
transformation(it)
}
/**
* Fold a [Iterable] of named data into a single [Data]
*/
public inline fun <T : Any, reified R : Any> Iterable<NamedData<T>>.foldNamedToData(
initial: R,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline block: suspend (result: R, data: NamedValueWithMeta<T>) -> R,
): Data<R> = reduceNamedToData(
coroutineContext, meta
) {
it.fold(initial) { acc, t -> block(acc, t) }
}
//DataSet operations
@DFInternal
public suspend fun <T : Any, R : Any> DataSet<T>.map(
outputType: KType,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
metaTransform: MutableMeta.() -> Unit = {},
block: suspend (NamedValueWithMeta<T>) -> R,
): DataTree<R> = DataTree<R>(outputType) {
forEach {
val newMeta = it.meta.toMutableMeta().apply(metaTransform).seal()
val d = Data(outputType, newMeta, coroutineContext, listOf(it)) {
block(it.awaitWithMeta())
}
data(it.name, d)
}
}
@OptIn(DFInternal::class)
public suspend inline fun <T : Any, reified R : Any> DataSet<T>.map(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
noinline metaTransform: MutableMeta.() -> Unit = {},
noinline block: suspend (NamedValueWithMeta<T>) -> R,
): DataTree<R> = map(typeOf<R>(), coroutineContext, metaTransform, block)
public inline fun <T : Any> DataSet<T>.forEach(block: (NamedData<T>) -> Unit) {
for (d in this) {
block(d)
}
}
public inline fun <T : Any, reified R : Any> DataSet<T>.reduceToData(
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline transformation: suspend (Iterable<NamedValueWithMeta<T>>) -> R,
): Data<R> = asIterable().reduceNamedToData(coroutineContext, meta, transformation)
public inline fun <T : Any, reified R : Any> DataSet<T>.foldToData(
initial: R,
coroutineContext: CoroutineContext = EmptyCoroutineContext,
meta: Meta = Meta.EMPTY,
crossinline block: suspend (result: R, data: NamedValueWithMeta<T>) -> R,
): Data<R> = asIterable().foldNamedToData(initial, coroutineContext, meta, block)

View File

@ -1,10 +0,0 @@
package hep.dataforge.data
import kotlin.reflect.KClass
/**
* Check that node is compatible with given type meaning that each element could be cast to the type
*/
actual fun DataNode<*>.checkType(type: KClass<*>) {
//Not supported in js yet
}

View File

@ -1,46 +0,0 @@
package hep.dataforge.data
import hep.dataforge.names.Name
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
fun <T : Any, R : Any> Data<T>.safeCast(type: KClass<R>): Data<R>? {
return if (type.isSubclassOf(type)) {
@Suppress("UNCHECKED_CAST")
Data.of(type, goal as Goal<R>, meta)
} else {
null
}
}
/**
* Filter a node by data and node type. Resulting node and its subnodes is guaranteed to have border type [type],
* but could contain empty nodes
*/
fun <T : Any, R : Any> DataNode<T>.cast(type: KClass<R>): DataNode<R> {
return if (this is CastDataNode) {
origin.cast(type)
} else {
CastDataNode(this, type)
}
}
inline fun <T : Any, reified R : Any> DataNode<T>.cast(): DataNode<R> = cast(R::class)
class CastDataNode<out T : Any>(val origin: DataNode<Any>, override val type: KClass<out T>) : DataNode<T> {
override fun get(name: Name): Data<T>? =
origin[name]?.safeCast(type)
override fun getNode(name: Name): DataNode<T>? {
return origin.getNode(name)?.cast(type)
}
override fun data(): Sequence<Pair<Name, Data<T>>> =
origin.data().mapNotNull { pair ->
pair.second.safeCast(type)?.let { pair.first to it }
}
override fun nodes(): Sequence<Pair<Name, DataNode<T>>> =
origin.nodes().map { it.first to it.second.cast(type) }
}

View File

@ -1,8 +0,0 @@
package hep.dataforge.data
import kotlinx.coroutines.runBlocking
/**
* Block the thread and get data content
*/
fun <T : Any> Data<T>.get(): T = runBlocking { await() }

View File

@ -1,13 +0,0 @@
package hep.dataforge.data
import kotlin.reflect.KClass
import kotlin.reflect.full.isSuperclassOf
/**
* Check that node is compatible with given type meaning that each element could be cast to the type
*/
actual fun DataNode<*>.checkType(type: KClass<*>) {
if (!type.isSuperclassOf(type)) {
error("$type expected, but $type received")
}
}

View File

@ -0,0 +1,2 @@
package space.kscience.dataforge.data

View File

@ -0,0 +1,85 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.reflect.KType
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.typeOf
/**
* Cast the node to given type if the cast is possible or return null
*/
@Suppress("UNCHECKED_CAST")
private fun <R : Any> Data<*>.castOrNull(type: KType): Data<R>? =
if (!this.type.isSubtypeOf(type)) {
null
} else {
object : Data<R> by (this as Data<R>) {
override val type: KType = type
}
}
/**
* Select all data matching given type and filters. Does not modify paths
*
* @param predicate addition filtering condition based on item name and meta. By default, accepts all
*/
@OptIn(DFExperimental::class)
public fun <R : Any> DataSet<*>.filterByType(
type: KType,
predicate: (name: Name, meta: Meta) -> Boolean = { _, _ -> true },
): DataSource<R> = object : DataSource<R> {
override val dataType = type
override val coroutineContext: CoroutineContext
get() = (this@filterByType as? DataSource)?.coroutineContext ?: EmptyCoroutineContext
override val meta: Meta get() = this@filterByType.meta
private fun checkDatum(name: Name, datum: Data<*>): Boolean = datum.type.isSubtypeOf(type)
&& predicate(name, datum.meta)
override fun iterator(): Iterator<NamedData<R>> = iterator {
for(d in this@filterByType){
if(checkDatum(d.name,d.data)){
@Suppress("UNCHECKED_CAST")
yield(d as NamedData<R>)
}
}
}
override fun get(name: Name): Data<R>? = this@filterByType[name]?.let { datum ->
if (checkDatum(name, datum)) datum.castOrNull(type) else null
}
override val updates: Flow<Name> = this@filterByType.updates.filter { name ->
get(name)?.let { datum ->
checkDatum(name, datum)
} ?: false
}
}
/**
* Select a single datum of the appropriate type
*/
public inline fun <reified R : Any> DataSet<*>.filterByType(
noinline predicate: (name: Name, meta: Meta) -> Boolean = { _, _ -> true },
): DataSet<R> = filterByType(typeOf<R>(), predicate)
/**
* Select a single datum if it is present and of given [type]
*/
public fun <R : Any> DataSet<*>.getByType(type: KType, name: Name): NamedData<R>? =
get(name)?.castOrNull<R>(type)?.named(name)
public inline fun <reified R : Any> DataSet<*>.getByType(name: Name): NamedData<R>? =
this@getByType.getByType(typeOf<R>(), name)
public inline fun <reified R : Any> DataSet<*>.getByType(name: String): NamedData<R>? =
this@getByType.getByType(typeOf<R>(), Name.parse(name))

View File

@ -0,0 +1,40 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.plus
/**
* Append data to node
*/
context(DataSetBuilder<T>) public infix fun <T : Any> String.put(data: Data<T>): Unit =
data(Name.parse(this), data)
/**
* Append node
*/
context(DataSetBuilder<T>) public infix fun <T : Any> String.put(dataSet: DataSet<T>): Unit =
node(Name.parse(this), dataSet)
/**
* Build and append node
*/
context(DataSetBuilder<T>) public infix fun <T : Any> String.put(
block: DataSetBuilder<T>.() -> Unit,
): Unit = node(Name.parse(this), block)
/**
* Copy given data set and mirror its changes to this [DataTreeBuilder] in [this@setAndObserve]. Returns an update [Job]
*/
context(DataSetBuilder<T>) public fun <T : Any> CoroutineScope.setAndWatch(
name: Name,
dataSet: DataSet<T>,
): Job = launch {
node(name, dataSet)
dataSet.updates.collect { nameInBranch ->
data(name + nameInBranch, dataSet.get(nameInBranch))
}
}

View File

@ -0,0 +1,50 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
import space.kscience.dataforge.actions.Action
import space.kscience.dataforge.actions.invoke
import space.kscience.dataforge.actions.map
import space.kscience.dataforge.misc.DFExperimental
import kotlin.test.assertEquals
@OptIn(DFExperimental::class, ExperimentalCoroutinesApi::class)
internal class ActionsTest {
@Test
fun testStaticMapAction() = runTest {
val data: DataTree<Int> = DataTree {
repeat(10) {
static(it.toString(), it)
}
}
val plusOne = Action.map<Int, Int> {
result { it + 1 }
}
val result = plusOne(data)
assertEquals(2, result["1"]?.await())
}
@Test
fun testDynamicMapAction() = runTest {
val data: DataSourceBuilder<Int> = DataSource()
val plusOne = Action.map<Int, Int> {
result { it + 1 }
}
val result = plusOne(data)
repeat(10) {
data.static(it.toString(), it)
}
delay(20)
assertEquals(2, result["1"]?.await())
data.close()
}
}

View File

@ -0,0 +1,91 @@
package space.kscience.dataforge.data
import kotlinx.coroutines.*
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.asName
import kotlin.test.Test
import kotlin.test.assertEquals
internal class DataTreeBuilderTest {
@Test
fun testTreeBuild() = runBlocking {
val node = DataTree<Any> {
"primary" put {
static("a", "a")
static("b", "b")
}
static("c.d", "c.d")
static("c.f", "c.f")
}
runBlocking {
assertEquals("a", node["primary.a"]?.await())
assertEquals("b", node["primary.b"]?.await())
assertEquals("c.d", node["c.d"]?.await())
assertEquals("c.f", node["c.f"]?.await())
}
}
@OptIn(DFExperimental::class)
@Test
fun testDataUpdate() = runBlocking {
val updateData: DataTree<Any> = DataTree {
"update" put {
"a" put Data.static("a")
"b" put Data.static("b")
}
}
val node = DataTree<Any> {
"primary" put {
static("a", "a")
static("b", "b")
}
static("root", "root")
populateFrom(updateData)
}
runBlocking {
assertEquals("a", node["update.a"]?.await())
assertEquals("a", node["primary.a"]?.await())
}
}
@Test
fun testDynamicUpdates() = runBlocking {
try {
lateinit var updateJob: Job
supervisorScope {
val subNode = DataSource<Int> {
updateJob = launch {
repeat(10) {
delay(10)
static("value", it)
}
delay(10)
}
}
launch {
subNode.updatesWithData.collect {
println(it)
}
}
val rootNode = DataSource<Int> {
setAndWatch("sub".asName(), subNode)
}
launch {
rootNode.updatesWithData.collect {
println(it)
}
}
updateJob.join()
assertEquals(9, rootNode["sub.value"]?.await())
cancel()
}
} catch (t: Throwable) {
if (t !is CancellationException) throw t
}
}
}

23
dataforge-io/README.md Normal file
View File

@ -0,0 +1,23 @@
# Module dataforge-io
IO module
## Usage
## Artifact:
The Maven coordinates of this project are `space.kscience:dataforge-io:0.7.0`.
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
//uncomment to access development builds
//maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
mavenCentral()
}
dependencies {
implementation("space.kscience:dataforge-io:0.7.0")
}
```

View File

@ -0,0 +1,473 @@
public final class hep/dataforge/io/BinaryMetaFormat : hep/dataforge/io/MetaFormat, hep/dataforge/io/MetaFormatFactory {
public static final field INSTANCE Lhep/dataforge/io/BinaryMetaFormat;
public fun getKey ()S
public fun getName ()Lhep/dataforge/names/Name;
public fun getShortName ()Ljava/lang/String;
public fun getType ()Lkotlin/reflect/KClass;
public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/MetaFormat;
public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object;
public fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta;
public final fun readMetaItem (Lkotlinx/io/Input;)Lhep/dataforge/meta/TypedMetaItem;
public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V
public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
public final fun writeValue (Lkotlinx/io/Output;Lhep/dataforge/values/Value;)V
}
public final class hep/dataforge/io/BinaryView : kotlinx/io/Binary {
public fun <init> (Lkotlinx/io/Binary;II)V
public fun getSize ()I
public fun read (IILkotlin/jvm/functions/Function1;)Ljava/lang/Object;
}
public abstract interface class hep/dataforge/io/Consumer {
public abstract fun consume (Lhep/dataforge/io/Envelope;)V
}
public final class hep/dataforge/io/DoubleIOFormat : hep/dataforge/io/IOFormat, hep/dataforge/io/IOFormatFactory {
public static final field INSTANCE Lhep/dataforge/io/DoubleIOFormat;
public fun getName ()Lhep/dataforge/names/Name;
public fun getType ()Lkotlin/reflect/KClass;
public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/IOFormat;
public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object;
public fun readObject (Lkotlinx/io/Input;)Ljava/lang/Double;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeObject (Lkotlinx/io/Output;D)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}
public abstract interface class hep/dataforge/io/Envelope {
public static final field Companion Lhep/dataforge/io/Envelope$Companion;
public abstract fun getData ()Lkotlinx/io/Binary;
public abstract fun getMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/io/Envelope$Companion {
public final fun getENVELOPE_DATA_ID_KEY ()Lhep/dataforge/names/Name;
public final fun getENVELOPE_DATA_TYPE_KEY ()Lhep/dataforge/names/Name;
public final fun getENVELOPE_DESCRIPTION_KEY ()Lhep/dataforge/names/Name;
public final fun getENVELOPE_NAME_KEY ()Lhep/dataforge/names/Name;
public final fun getENVELOPE_NODE_KEY ()Lhep/dataforge/names/Name;
public final fun getENVELOPE_TYPE_KEY ()Lhep/dataforge/names/Name;
public final fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/io/Envelope;
}
public final class hep/dataforge/io/EnvelopeBuilder : hep/dataforge/io/Envelope {
public fun <init> ()V
public final fun data (Lkotlin/jvm/functions/Function1;)V
public fun getData ()Lkotlinx/io/Binary;
public final fun getDataID ()Ljava/lang/String;
public final fun getDataType ()Ljava/lang/String;
public final fun getDescription ()Ljava/lang/String;
public fun getMeta ()Lhep/dataforge/meta/Meta;
public final fun getName ()Ljava/lang/String;
public final fun getType ()Ljava/lang/String;
public final fun meta (Lkotlin/jvm/functions/Function1;)V
public final fun seal ()Lhep/dataforge/io/Envelope;
public fun setData (Lkotlinx/io/Binary;)V
public final fun setDataID (Ljava/lang/String;)V
public final fun setDataType (Ljava/lang/String;)V
public final fun setDescription (Ljava/lang/String;)V
public fun setMeta (Lhep/dataforge/meta/Meta;)V
public final fun setName (Ljava/lang/String;)V
public final fun setType (Ljava/lang/String;)V
}
public final class hep/dataforge/io/EnvelopeBuilderKt {
public static final fun Envelope (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/io/Envelope;
}
public abstract interface class hep/dataforge/io/EnvelopeFormat : hep/dataforge/io/IOFormat {
public abstract fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory;
public abstract fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope;
public abstract fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope;
public abstract fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V
public abstract fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V
}
public final class hep/dataforge/io/EnvelopeFormat$DefaultImpls {
public static fun getDefaultMetaFormat (Lhep/dataforge/io/EnvelopeFormat;)Lhep/dataforge/io/MetaFormatFactory;
public static synthetic fun writeEnvelope$default (Lhep/dataforge/io/EnvelopeFormat;Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)V
public static fun writeObject (Lhep/dataforge/io/EnvelopeFormat;Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V
}
public abstract interface class hep/dataforge/io/EnvelopeFormatFactory : hep/dataforge/io/EnvelopeFormat, hep/dataforge/io/IOFormatFactory {
public static final field Companion Lhep/dataforge/io/EnvelopeFormatFactory$Companion;
public static final field ENVELOPE_FORMAT_TYPE Ljava/lang/String;
public abstract fun getName ()Lhep/dataforge/names/Name;
public abstract fun getType ()Lkotlin/reflect/KClass;
public abstract fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/EnvelopeFormat;
public abstract fun peekFormat (Lhep/dataforge/io/IOPlugin;Lkotlinx/io/Input;)Lhep/dataforge/io/EnvelopeFormat;
}
public final class hep/dataforge/io/EnvelopeFormatFactory$Companion {
public static final field ENVELOPE_FORMAT_TYPE Ljava/lang/String;
}
public final class hep/dataforge/io/EnvelopeFormatFactory$DefaultImpls {
public static fun getDefaultMetaFormat (Lhep/dataforge/io/EnvelopeFormatFactory;)Lhep/dataforge/io/MetaFormatFactory;
public static fun getName (Lhep/dataforge/io/EnvelopeFormatFactory;)Lhep/dataforge/names/Name;
public static fun getType (Lhep/dataforge/io/EnvelopeFormatFactory;)Lkotlin/reflect/KClass;
public static fun toMeta (Lhep/dataforge/io/EnvelopeFormatFactory;)Lhep/dataforge/meta/Meta;
public static fun writeObject (Lhep/dataforge/io/EnvelopeFormatFactory;Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V
}
public final class hep/dataforge/io/EnvelopeFormatKt {
public static final fun read (Lhep/dataforge/io/EnvelopeFormat;Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope;
}
public final class hep/dataforge/io/EnvelopeKt {
public static final fun contentEquals (Lhep/dataforge/io/Envelope;Lhep/dataforge/io/Envelope;)Z
public static final fun dataEquals (Lhep/dataforge/io/Envelope;Lhep/dataforge/io/Envelope;)Z
public static final fun getDataID (Lhep/dataforge/io/Envelope;)Ljava/lang/String;
public static final fun getDataType (Lhep/dataforge/io/Envelope;)Ljava/lang/String;
public static final fun getDescription (Lhep/dataforge/io/Envelope;)Ljava/lang/String;
public static final fun getType (Lhep/dataforge/io/Envelope;)Ljava/lang/String;
public static final fun metaEquals (Lhep/dataforge/io/Envelope;Lhep/dataforge/io/Envelope;)Z
public static final fun withMetaLayers (Lhep/dataforge/io/Envelope;[Lhep/dataforge/meta/Meta;)Lhep/dataforge/io/Envelope;
}
public final class hep/dataforge/io/EnvelopePart {
public fun <init> (Lkotlinx/io/Binary;Lhep/dataforge/meta/Meta;)V
public final fun component1 ()Lkotlinx/io/Binary;
public final fun component2 ()Lhep/dataforge/meta/Meta;
public final fun copy (Lkotlinx/io/Binary;Lhep/dataforge/meta/Meta;)Lhep/dataforge/io/EnvelopePart;
public static synthetic fun copy$default (Lhep/dataforge/io/EnvelopePart;Lkotlinx/io/Binary;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/io/EnvelopePart;
public fun equals (Ljava/lang/Object;)Z
public final fun getBinary ()Lkotlinx/io/Binary;
public final fun getDescription ()Lhep/dataforge/meta/Meta;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class hep/dataforge/io/EnvelopePartsKt {
public static final fun envelope (Lhep/dataforge/io/EnvelopePart;Lhep/dataforge/io/EnvelopeFormat;)Lhep/dataforge/io/Envelope;
public static final fun envelope (Lhep/dataforge/io/EnvelopePart;Lhep/dataforge/io/IOPlugin;)Lhep/dataforge/io/Envelope;
public static final fun envelopes (Lhep/dataforge/io/EnvelopeBuilder;Ljava/util/List;Lhep/dataforge/io/EnvelopeFormat;Ljava/lang/String;)V
public static synthetic fun envelopes$default (Lhep/dataforge/io/EnvelopeBuilder;Ljava/util/List;Lhep/dataforge/io/EnvelopeFormat;Ljava/lang/String;ILjava/lang/Object;)V
public static final fun getName (Lhep/dataforge/io/EnvelopePart;)Ljava/lang/String;
public static final fun multipart (Lhep/dataforge/io/EnvelopeBuilder;Ljava/util/List;Ljava/lang/String;)V
public static synthetic fun multipart$default (Lhep/dataforge/io/EnvelopeBuilder;Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)V
public static final fun parts (Lhep/dataforge/io/Envelope;)Ljava/util/List;
}
public final class hep/dataforge/io/FileIOKt {
public static final fun append (Ljava/nio/file/Path;Lkotlin/jvm/functions/Function1;)V
public static final fun getDATA_FILE_NAME (Lhep/dataforge/io/IOPlugin$Companion;)Ljava/lang/String;
public static final fun getMETA_FILE_NAME (Lhep/dataforge/io/IOPlugin$Companion;)Ljava/lang/String;
public static final fun peekBinaryFormat (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;)Lhep/dataforge/io/EnvelopeFormat;
public static final fun read (Ljava/nio/file/Path;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public static final fun readEnvelope (Ljava/nio/file/Path;Lhep/dataforge/io/EnvelopeFormat;)Lhep/dataforge/io/Envelope;
public static final fun readEnvelopeFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;ZLkotlin/jvm/functions/Function2;)Lhep/dataforge/io/Envelope;
public static synthetic fun readEnvelopeFile$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lhep/dataforge/io/Envelope;
public static final fun readMetaFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/MetaFormat;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta;
public static synthetic fun readMetaFile$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/MetaFormat;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Lhep/dataforge/meta/Meta;
public static final fun rewrite (Ljava/nio/file/Path;Lkotlin/jvm/functions/Function1;)V
public static final fun write (Ljava/nio/file/Path;Lkotlin/jvm/functions/Function1;)V
public static final fun writeEnvelopeDirectory (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;)V
public static synthetic fun writeEnvelopeDirectory$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;ILjava/lang/Object;)V
public static final fun writeEnvelopeFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/EnvelopeFormat;Lhep/dataforge/io/MetaFormatFactory;)V
public static synthetic fun writeEnvelopeFile$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/EnvelopeFormat;Lhep/dataforge/io/MetaFormatFactory;ILjava/lang/Object;)V
public static final fun writeMetaFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/meta/Meta;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V
public static synthetic fun writeMetaFile$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/meta/Meta;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)V
public static final fun writeToFile (Lhep/dataforge/io/IOFormat;Ljava/nio/file/Path;Ljava/lang/Object;)V
}
public abstract interface class hep/dataforge/io/IOFormat : hep/dataforge/meta/MetaRepr {
public static final field Companion Lhep/dataforge/io/IOFormat$Companion;
public abstract fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public abstract fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}
public final class hep/dataforge/io/IOFormat$Companion {
public final fun getMETA_KEY ()Lhep/dataforge/names/Name;
public final fun getNAME_KEY ()Lhep/dataforge/names/Name;
}
public abstract interface class hep/dataforge/io/IOFormatFactory : hep/dataforge/context/Factory, hep/dataforge/context/Named, hep/dataforge/meta/MetaRepr {
public static final field Companion Lhep/dataforge/io/IOFormatFactory$Companion;
public static final field IO_FORMAT_TYPE Ljava/lang/String;
public abstract fun getType ()Lkotlin/reflect/KClass;
public abstract fun toMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/io/IOFormatFactory$Companion {
public static final field IO_FORMAT_TYPE Ljava/lang/String;
}
public final class hep/dataforge/io/IOFormatFactory$DefaultImpls {
public static fun toMeta (Lhep/dataforge/io/IOFormatFactory;)Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/io/IOFormatKt {
public static final fun fill (Lkotlinx/io/pool/ObjectPool;Lkotlin/jvm/functions/Function1;)Ljava/nio/ByteBuffer;
public static final fun readWith (Lkotlinx/io/Binary;Lhep/dataforge/io/IOFormat;)Ljava/lang/Object;
public static final fun readWith (Lkotlinx/io/Input;Lhep/dataforge/io/IOFormat;)Ljava/lang/Object;
public static final fun toBinary (Lhep/dataforge/io/IOFormat;Ljava/lang/Object;)Lkotlinx/io/Binary;
public static final fun writeWith (Lkotlinx/io/Output;Lhep/dataforge/io/IOFormat;Ljava/lang/Object;)V
}
public final class hep/dataforge/io/IOPlugin : hep/dataforge/context/AbstractPlugin {
public static final field Companion Lhep/dataforge/io/IOPlugin$Companion;
public fun <init> (Lhep/dataforge/meta/Meta;)V
public fun content (Ljava/lang/String;)Ljava/util/Map;
public final fun getEnvelopeFormatFactories ()Ljava/util/Collection;
public final fun getIoFormatFactories ()Ljava/util/Collection;
public final fun getMetaFormatFactories ()Ljava/util/Collection;
public fun getTag ()Lhep/dataforge/context/PluginTag;
public final fun resolveEnvelopeFormat (Lhep/dataforge/meta/TypedMetaItem;)Lhep/dataforge/io/EnvelopeFormat;
public final fun resolveIOFormat (Lhep/dataforge/meta/TypedMetaItem;Lkotlin/reflect/KClass;)Lhep/dataforge/io/IOFormat;
public final fun resolveMetaFormat (Ljava/lang/String;Lhep/dataforge/meta/Meta;)Lhep/dataforge/io/MetaFormat;
public final fun resolveMetaFormat (SLhep/dataforge/meta/Meta;)Lhep/dataforge/io/MetaFormat;
public static synthetic fun resolveMetaFormat$default (Lhep/dataforge/io/IOPlugin;Ljava/lang/String;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/io/MetaFormat;
public static synthetic fun resolveMetaFormat$default (Lhep/dataforge/io/IOPlugin;SLhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/io/MetaFormat;
}
public final class hep/dataforge/io/IOPlugin$Companion : hep/dataforge/context/PluginFactory {
public final fun getDefaultEnvelopeFormats ()Ljava/util/List;
public final fun getDefaultMetaFormats ()Ljava/util/List;
public fun getTag ()Lhep/dataforge/context/PluginTag;
public fun getType ()Lkotlin/reflect/KClass;
public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/IOPlugin;
public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object;
}
public final class hep/dataforge/io/IOPluginKt {
public static final fun getIo (Lhep/dataforge/context/Context;)Lhep/dataforge/io/IOPlugin;
}
public final class hep/dataforge/io/IoMiscKt {
public static final fun Binary (ILkotlin/jvm/functions/Function1;)Lkotlinx/io/Binary;
public static synthetic fun Binary$default (ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/io/Binary;
public static final fun buildByteArray (ILkotlin/jvm/functions/Function1;)[B
public static synthetic fun buildByteArray$default (ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)[B
public static final fun get (Lkotlinx/io/Binary;Lkotlin/ranges/IntRange;)Lhep/dataforge/io/BinaryView;
public static final fun readRawString (Lkotlinx/io/Input;I)Ljava/lang/String;
public static final fun view (Lkotlinx/io/Binary;II)Lhep/dataforge/io/BinaryView;
public static final fun writeRawString (Lkotlinx/io/Output;Ljava/lang/String;)V
}
public final class hep/dataforge/io/JsonMetaFormat : hep/dataforge/io/MetaFormat {
public static final field Companion Lhep/dataforge/io/JsonMetaFormat$Companion;
public fun <init> ()V
public fun <init> (Lkotlinx/serialization/json/Json;)V
public synthetic fun <init> (Lkotlinx/serialization/json/Json;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta;
public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V
public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}
public final class hep/dataforge/io/JsonMetaFormat$Companion : hep/dataforge/io/MetaFormatFactory {
public final fun getDEFAULT_JSON ()Lkotlinx/serialization/json/Json;
public fun getKey ()S
public fun getName ()Lhep/dataforge/names/Name;
public fun getShortName ()Ljava/lang/String;
public fun getType ()Lkotlin/reflect/KClass;
public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/MetaFormat;
public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object;
public fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta;
public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V
public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}
public final class hep/dataforge/io/ListIOFormat : hep/dataforge/io/IOFormat {
public fun <init> (Lhep/dataforge/io/IOFormat;)V
public final fun getFormat ()Lhep/dataforge/io/IOFormat;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun readObject (Lkotlinx/io/Input;)Ljava/util/List;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
public fun writeObject (Lkotlinx/io/Output;Ljava/util/List;)V
}
public abstract interface class hep/dataforge/io/MetaFormat : hep/dataforge/io/IOFormat {
public abstract fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta;
public abstract fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta;
public abstract fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V
public abstract fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V
}
public final class hep/dataforge/io/MetaFormat$DefaultImpls {
public static synthetic fun readMeta$default (Lhep/dataforge/io/MetaFormat;Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Lhep/dataforge/meta/Meta;
public static fun readObject (Lhep/dataforge/io/MetaFormat;Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta;
public static synthetic fun writeMeta$default (Lhep/dataforge/io/MetaFormat;Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)V
public static fun writeObject (Lhep/dataforge/io/MetaFormat;Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V
}
public abstract interface class hep/dataforge/io/MetaFormatFactory : hep/dataforge/io/IOFormatFactory, hep/dataforge/io/MetaFormat {
public static final field Companion Lhep/dataforge/io/MetaFormatFactory$Companion;
public static final field META_FORMAT_TYPE Ljava/lang/String;
public abstract fun getKey ()S
public abstract fun getName ()Lhep/dataforge/names/Name;
public abstract fun getShortName ()Ljava/lang/String;
public abstract fun getType ()Lkotlin/reflect/KClass;
public abstract fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/MetaFormat;
}
public final class hep/dataforge/io/MetaFormatFactory$Companion {
public static final field META_FORMAT_TYPE Ljava/lang/String;
}
public final class hep/dataforge/io/MetaFormatFactory$DefaultImpls {
public static fun getKey (Lhep/dataforge/io/MetaFormatFactory;)S
public static fun getName (Lhep/dataforge/io/MetaFormatFactory;)Lhep/dataforge/names/Name;
public static fun getType (Lhep/dataforge/io/MetaFormatFactory;)Lkotlin/reflect/KClass;
public static fun readObject (Lhep/dataforge/io/MetaFormatFactory;Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta;
public static fun toMeta (Lhep/dataforge/io/MetaFormatFactory;)Lhep/dataforge/meta/Meta;
public static fun writeObject (Lhep/dataforge/io/MetaFormatFactory;Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V
}
public final class hep/dataforge/io/MetaFormatKt {
public static final fun parse (Lhep/dataforge/io/MetaFormat;Ljava/lang/String;)Lhep/dataforge/meta/Meta;
public static final fun parse (Lhep/dataforge/io/MetaFormatFactory;Ljava/lang/String;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Meta;
public static final fun toString (Lhep/dataforge/meta/Meta;Lhep/dataforge/io/MetaFormat;)Ljava/lang/String;
public static final fun toString (Lhep/dataforge/meta/Meta;Lhep/dataforge/io/MetaFormatFactory;)Ljava/lang/String;
}
public final class hep/dataforge/io/PartialEnvelope {
public synthetic fun <init> (Lhep/dataforge/meta/Meta;ILkotlin/ULong;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lhep/dataforge/meta/Meta;
public final fun component2-pVg5ArA ()I
public final fun component3-6VbMDqA ()Lkotlin/ULong;
public final fun copy-BMK4sig (Lhep/dataforge/meta/Meta;ILkotlin/ULong;)Lhep/dataforge/io/PartialEnvelope;
public static synthetic fun copy-BMK4sig$default (Lhep/dataforge/io/PartialEnvelope;Lhep/dataforge/meta/Meta;ILkotlin/ULong;ILjava/lang/Object;)Lhep/dataforge/io/PartialEnvelope;
public fun equals (Ljava/lang/Object;)Z
public final fun getDataOffset-pVg5ArA ()I
public final fun getDataSize-6VbMDqA ()Lkotlin/ULong;
public final fun getMeta ()Lhep/dataforge/meta/Meta;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class hep/dataforge/io/ProxyEnvelope : hep/dataforge/io/Envelope {
public fun <init> (Lhep/dataforge/io/Envelope;[Lhep/dataforge/meta/Meta;)V
public fun getData ()Lkotlinx/io/Binary;
public fun getMeta ()Lhep/dataforge/meta/Laminate;
public synthetic fun getMeta ()Lhep/dataforge/meta/Meta;
public final fun getSource ()Lhep/dataforge/io/Envelope;
}
public abstract interface class hep/dataforge/io/Responder {
public abstract fun respond (Lhep/dataforge/io/Envelope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}
public final class hep/dataforge/io/SimpleEnvelope : hep/dataforge/io/Envelope {
public fun <init> (Lhep/dataforge/meta/Meta;Lkotlinx/io/Binary;)V
public fun getData ()Lkotlinx/io/Binary;
public fun getMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/io/StreamsIOKt {
public static final fun read (Ljava/io/InputStream;ILkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public static final fun read (Ljava/io/InputStream;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public static final fun readBlocking (Ljava/io/InputStream;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public static final fun write (Ljava/io/OutputStream;Lkotlin/jvm/functions/Function1;)V
}
public final class hep/dataforge/io/TaggedEnvelopeFormat : hep/dataforge/io/EnvelopeFormat {
public static final field Companion Lhep/dataforge/io/TaggedEnvelopeFormat$Companion;
public fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;)V
public synthetic fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory;
public final fun getIo ()Lhep/dataforge/io/IOPlugin;
public final fun getVersion ()Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;
public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V
public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}
public final class hep/dataforge/io/TaggedEnvelopeFormat$Companion : hep/dataforge/io/EnvelopeFormatFactory {
public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory;
public fun getName ()Lhep/dataforge/names/Name;
public fun getType ()Lkotlin/reflect/KClass;
public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/EnvelopeFormat;
public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object;
public fun peekFormat (Lhep/dataforge/io/IOPlugin;Lkotlinx/io/Input;)Lhep/dataforge/io/EnvelopeFormat;
public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V
public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}
public final class hep/dataforge/io/TaggedEnvelopeFormat$VERSION : java/lang/Enum {
public static final field DF02 Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;
public static final field DF03 Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;
public final fun getTagSize-pVg5ArA ()I
public static fun valueOf (Ljava/lang/String;)Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;
public static fun values ()[Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;
}
public final class hep/dataforge/io/TaglessEnvelopeFormat : hep/dataforge/io/EnvelopeFormat {
public static final field Companion Lhep/dataforge/io/TaglessEnvelopeFormat$Companion;
public static final field DATA_LENGTH_PROPERTY Ljava/lang/String;
public static final field DATA_START_PROPERTY Ljava/lang/String;
public static final field DEFAULT_DATA_START Ljava/lang/String;
public static final field DEFAULT_META_START Ljava/lang/String;
public static final field META_LENGTH_PROPERTY Ljava/lang/String;
public static final field META_START_PROPERTY Ljava/lang/String;
public static final field META_TYPE_PROPERTY Ljava/lang/String;
public static final field TAGLESS_ENVELOPE_HEADER Ljava/lang/String;
public static final field TAGLESS_ENVELOPE_TYPE Ljava/lang/String;
public static final field code I
public fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/meta/Meta;)V
public synthetic fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory;
public final fun getIo ()Lhep/dataforge/io/IOPlugin;
public final fun getMeta ()Lhep/dataforge/meta/Meta;
public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V
public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}
public final class hep/dataforge/io/TaglessEnvelopeFormat$Companion : hep/dataforge/io/EnvelopeFormatFactory {
public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory;
public fun getName ()Lhep/dataforge/names/Name;
public fun getType ()Lkotlin/reflect/KClass;
public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/EnvelopeFormat;
public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object;
public fun peekFormat (Lhep/dataforge/io/IOPlugin;Lkotlinx/io/Input;)Lhep/dataforge/io/EnvelopeFormat;
public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V
public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}
public final class hep/dataforge/io/ValueIOFormat : hep/dataforge/io/IOFormat, hep/dataforge/io/IOFormatFactory {
public static final field INSTANCE Lhep/dataforge/io/ValueIOFormat;
public fun getName ()Lhep/dataforge/names/Name;
public fun getType ()Lkotlin/reflect/KClass;
public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/IOFormat;
public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object;
public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/values/Value;
public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object;
public fun toMeta ()Lhep/dataforge/meta/Meta;
public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/values/Value;)V
public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V
}

Some files were not shown because too many files have changed in this diff Show More